Compare commits

...

47 Commits

Author SHA1 Message Date
Scott Walters
c35791c506 Merge pull request #2 from rejitnatarajan/pod-fix
missing asterisk fixes pod error
2015-02-11 22:46:16 -06:00
rejit natarajan
b803f83abd missing asterisk fixes pod error
small fix for pod error http://cpants.cpanauthors.org/dist/SOAP-WSDL/errors
2015-02-12 09:55:29 +05:30
Scott Walters
e95ff8baba Changelog entries for 3.002, too late for release. oops. and what exactly where the 3.001 changes? oh well. 2014-09-16 17:49:01 -04:00
Scott Walters
cad782dbf2 bump version to 3.002, and also change each file from having their own version number to referring to $SOAP::WSDL::VERSION since they aren't really individually versions anyway but just copies of that number. 2014-09-16 17:40:18 -04:00
Scott Walters
99c5eb4dd7 remove META.yml (I still don't know how that's supposed to work) and Makefile (which I do know wasn't supposed to be in git) 2014-09-16 03:30:20 -04:00
Scott Walters
a1e9927846 Declare dependency on Class::Load
Thanks ANDYK!
Ref Bug #98628 for SOAP-WSDL: Undeclared dependency on Class::Load
https://rt.cpan.org/Public/Bug/Display.html?id=98628
2014-09-16 03:30:20 -04:00
Scott Walters
ba407622f5 Merge pull request #1 from szabgab/patch-1
link to GitHub from META files
2014-08-30 03:52:40 -04:00
Gabor Szabo
5b9f3c640b link to GitHub from META files 2014-08-30 10:27:21 +03:00
Scott Walters
ed715a4c88 smoke testing looks pretty good, only failing on amd64-netbsd machines and one random Linux machine (I should look why but I really don't want to know), so, bump version to 3.001 and do a release.
FAIL    5.10.1  NetBSD  6.1.4   amd64-netbsd
FAIL    5.14.2  GNU/Linux       3.11.0-18-generic       x86_64-linux-thread-multi
FAIL    5.10.1  NetBSD  6.1.4   amd64-netbsd-thread-multi
2014-08-29 15:05:06 -04:00
Scott Walters
f5787f6057 version bump to 3.00.0_2 and Changes entry 2014-08-28 21:16:50 -04:00
Scott Walters
374793ef68 get rid of Build.PL; we use ExtUtils::MakeMaker now. 2014-08-28 21:08:13 -04:00
Scott Walters
7f6af60ed8 oops, global version search and replace ruined a comment. leave it ruined 2014-08-28 21:05:13 -04:00
Scott Walters
37740b870a fix a hash randomization bug that was causing random failures in t/SOAP/WSDL/05_simpleType-list.t 2014-08-28 21:03:39 -04:00
Scott Walters
31f5deacf5 2624a9 for #86142, adding the XML declaration to the output, broke another part of the system, so work around that.
I accidentally stopped doing "recursive" tests (tests in subdirs) at some point and missed some of this fun breakage.
2014-08-28 21:01:51 -04:00
Scott Walters
3197383a7d update POD; thought I commit this already... ? 2014-08-28 20:38:31 -04:00
Scott Walters
285ffa463c okay, dam@cpan.org's fix for using not using ->usa('UNIVERSAL') to test if something loaded apparently works in a situation where mine doesn't, that was causing tests to fail. 2014-08-28 18:26:41 -04:00
Scott Walters
35321ce5d0 run tests recursively under ExtUtils::MakeMaker. 2014-08-28 16:25:55 -04:00
Scott Walters
08b156a546 take Module::Build out of inc. it doesn't work. don't use it. 2014-08-28 16:25:29 -04:00
Scott Walters
605732b836 https://rt.cpan.org/Ticket/Display.html?id=82028 -- POD error results in broken link generated 2014-08-27 18:28:43 -04:00
Scott Walters
1994b36d8b switch from Module::Build to Make::Maker based Makefile.PL after Module::Build vomited on trying to 'make dist', and then when that was fixed, generated a completely busted dist without error. good riddance. 2014-08-27 17:53:50 -04:00
Scott Walters
f3ae85aed5 default directory for t/098_pod.t. not sure why it was doing @dir = (); if(ENV var) { @dir = 'some dir that exists' }. this would make a path analysis tool cry. 2014-08-27 17:52:41 -04:00
Scott Walters
7d81cfce87 bump version to 3.00.00_1; update POD a bit; include contact info for myself; declare this module deprecated and in maintenance mode; include Module::Build in the 'inc' dir to avoid a warning about it being deprecated from core inclusion; add mention of the UNIVERSAL->isa() bug created by Class::Std::Fast to the POD for BUGS AND LIMITATIONS. 2014-08-27 17:39:52 -04:00
Scott Walters
2624a9d5c0 applied patch from ticket #86142: Missing XML declaration in request
https://rt.cpan.org/Public/Bug/Display.html?id=86142
tests still pass, so, good enough, right?
2014-08-21 20:50:56 -04:00
Scott Walters
45982ff330 Huh. Between 5.12 and 5.16 somewhere, the behavior of ClassName->isa('UNIVERSAL') changed.
It used to be that that would return true if and only if that namespace existed.
Now it always returns true for any random non-existant made up name.
Changed this to do ->can() on a known existing method modules with this API have (serialize)
instead after floundering around for a bit.  exists ${"main::"}{$type.'::'} worked a little
bit but made it barf for some reason I didn't investigate.
This is the problem apparently behind the previous "haunted house level shit" fixes and
reversions.  This thing does automatically load these modules on the fly.  Would be nice
if the unit tests had some comments in them.
2014-08-21 08:37:49 -04:00
Scott Walters
cfd5892b18 Revert "was barfing with "Can't locate object method "new" via package "MyElement" (perhaps you forgot to load "MyElement"?) at lib/SOAP/WSDL/XSD/Typelib/Comple"
ref haunted house level shit going weird message in previous revert.

This reverts commit d221e87b29.
2014-08-21 07:48:30 -04:00
Scott Walters
6e95d01610 Revert "maybe I'm doing the wrong thing by adding use lines for test modules"
Wow.  Even with the "fix" in, it runs correctly once, and then starts vomiting
with a similar error again as before the fix.  it'll fail 20 times in a
row, then pass 20 times in a row.  there's some haunted house level
shit going wrong here.

This reverts commit b121a061d8.
2014-08-21 07:47:02 -04:00
Scott Walters
b121a061d8 maybe I'm doing the wrong thing by adding use lines for test modules
that unit tests use.  maybe there's some magic that's supposed to
automatically use those things, even though they're hidden in deeply
buried paths with no machine predictable naming scheme.  I can't
imagine that these unit tests passed before unless there is/was
some magic.  I hobbled this in to working with a use lib and a
use for the module, but after doing this second one of these,
I'm having serious doubts about whether I'm just spackling over
the problem.
2014-08-21 07:37:22 -04:00
Scott Walters
d2f324a7f2 oops, changing error messages breaks tests. make them match again. don't change the tests. change the error messages. that way the error message's awkwardness hints at the code's awkwardness. 2014-08-21 07:34:19 -04:00
Scott Walters
f2ce9511e0 I don't get it. There were two calls to get_port() right next to
each other, in the very same ? :, and one of them had a ->[0]
tacked on the end and the other one didn't.  Well guess what...
the one without was returning an arrayref, which caused these
failures in the unit tests:
Can't call method "get_binding" on unblessed reference at /home/scott/projects/SOAP-WSDL/blib/lib/SOAP/WSDL.pm line 186.
2014-08-21 07:27:58 -04:00
Scott Walters
50c8d5b31f oh, look, ComplexType.pm has cut and paste hash reversing code
from SimpleType.pm.  that means that we can cut and paste the
fix from SimpleType.pm into ComplexType.pm.  how many wrongs
make a right?  I forget.
2014-08-21 07:26:30 -04:00
Scott Walters
47dc61bd9e protip: reverse %hash with '#default' => 'urn:myNamespace', 'tns' =>
'urn:myNamespace' results in misery.  random hash ordering made a pile of
tests in t/003_wsdl_based_serializer.t randomly pass and fail in unison.
I smelled a smell.
2014-08-21 06:32:11 -04:00
Scott Walters
3670df3e69 "vectors" (totally not the same thing as a vector in other languages or on a Cray 1)
have been deprecated and removed.  pretend like they never existed.
2014-08-21 05:20:56 -04:00
Scott Walters
d221e87b29 was barfing with "Can't locate object method "new" via package "MyElement" (perhaps you forgot to load "MyElement"?) at lib/SOAP/WSDL/XSD/Typelib/Comple
xType.pm line 213.".  Okay, then, MyElement.pm exists in t/lib.  Let's try
using it.  And it worked.  Incidentally, the code at lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm is heinous.
2014-08-21 05:17:05 -04:00
Scott Walters
001c36f8e8 fix two instances of the "Can't modify non-lvalue subroutine call at lib/SOAP/WSDL.pm line 167." error.
it looks like the author wrote

    return $a ? $b : $c = $d

Intending it to mean:

    return $a ? $b : ($c = $d);

... but perl parses it as:

    return ( $a ? $b : $c) = $d;

... and perl 5.16 is more astute about lvalue errors like that.
2014-08-20 08:37:33 -04:00
Martin Kutter
9023aa06a4 import SOAP-WSDL 2.00.10 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.10
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.10.tar.gz
2009-12-12 19:49:03 -08:00
Martin Kutter
3b30e8d0e2 import SOAP-WSDL 2.00.09 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.09
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.09.tar.gz
2009-12-12 19:49:02 -08:00
Martin Kutter
fb9fd4a2b1 import SOAP-WSDL 2.00.08 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.08
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.08.tar.gz
2009-12-12 19:49:00 -08:00
Martin Kutter
bfc3247583 import SOAP-WSDL 2.00.07 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.07
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.07.tar.gz
2009-12-12 19:48:57 -08:00
Martin Kutter
3de318be40 import SOAP-WSDL 2.00.06 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.06
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.06.tar.gz
2009-12-12 19:48:54 -08:00
Martin Kutter
c2ac24dd0f import SOAP-WSDL 2.00.05 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.05
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.05.tar.gz
2009-12-12 19:48:45 -08:00
Martin Kutter
c3e3d1908e import SOAP-WSDL 2.00.04 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.04
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.04.tar.gz
2009-12-12 19:48:44 -08:00
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
Martin Kutter
0cbf981665 import SOAP-WSDL 2.00_33 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_33
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_33.tar.gz
2009-12-12 19:48:28 -08:00
Martin Kutter
51db446428 import SOAP-WSDL 2.00_32 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_32
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_32.tar.gz
2009-12-12 19:48:24 -08:00
Martin Kutter
f0b3bdc201 import SOAP-WSDL 2.00_31 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_31
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_31.tar.gz
2009-12-12 19:48:21 -08:00
327 changed files with 13336 additions and 7434 deletions

View File

@@ -1,53 +0,0 @@
use Module::Build;
use version;
$build = Module::Build->new(
dist_author => 'Martin Kutter <martin.kutter@fen-net.de>',
create_makefile_pl => 'passthrough',
dist_abstract => 'SOAP with WSDL support',
dist_name => 'SOAP-WSDL',
dist_version => '2.00_29',
module_name => 'SOAP::WSDL',
license => 'artistic',
requires => {
# 5.6.x is way too buggy and has no unicode support
# for us. SOAP-WSDL relies on unicode (WS-I demands it)
# and triggers several 5.6 bugs...
'perl' => q(5.8.0),
'Class::Std::Fast' => qv(0.0.5),
'Data::Dumper' => 0,
'Date::Parse' => 0,
'Date::Format' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'Getopt::Long' => 0,
'List::Util' => 0,
'LWP::UserAgent' => 0,
'Template' => 0,
'Term::ReadKey' => 0,
'XML::Parser::Expat' => 0,
},
buildrequires => {
'Class::Std::Fast' => qv(0.0.5),
'Cwd' => 0,
'Date::Parse' => 0,
'Date::Format' => 0,
'Getopt::Long' => 0,
'List::Util' => 0,
'LWP::UserAgent' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'File::Spec' => 0,
'Storable' => 0,
'Test::More' => 0,
'Template' => 0,
'XML::Parser::Expat' => 0,
},
recursive_test_files => 1,
meta_add => {
no_index => {
directory => 'lib/SOAP/WSDL/Generator/Template/XSD/',
},
}
);
$build->add_build_element('tt');
$build->create_build_script;

649
Changes

File diff suppressed because it is too large Load Diff

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

123
MANIFEST
View File

@@ -1,10 +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
@@ -15,6 +20,16 @@ example/genericbarcode.pl
example/hello.pl
example/hello_compile.pl
example/hello_lite.pl
example/java/cxf/.classpath
example/java/cxf/.settings/org.eclipse.jdt.core.prefs
example/java/cxf/.settings/org.maven.ide.eclipse.prefs
example/java/cxf/11_helloworld.wsdl
example/java/cxf/jax-binding.xml
example/java/cxf/pom.xml
example/java/cxf/README
example/java/cxf/src/main/resources/cxf.xml
example/java/cxf/src/test/java/helloworld/HelloWorldTest.java
example/java/cxf/src/test/resources/test-context.xml
example/lib/MyElements/CountCookies.pm
example/lib/MyElements/CountCookiesResponse.pm
example/lib/MyElements/GenerateBarCode.pm
@@ -64,6 +79,7 @@ example/lib/MyTypes/test2.pm
example/lib/MyTypes/testExtended.pm
example/person.pl
example/person_compile.pl
example/server/hello_simple.pl
example/visitor/visitor.pl
example/weather.pl
example/weather_wsdl.pl
@@ -72,6 +88,7 @@ example/wsdl/FortuneCookie.xml
example/wsdl/genericbarcode.xml
example/wsdl/globalweather.xml
example/wsdl/Person.wsdl
example/wsdl/person.xml
HACKING
lib/SOAP/WSDL.pm
lib/SOAP/WSDL/Base.pm
@@ -91,9 +108,12 @@ lib/SOAP/WSDL/Factory/Deserializer.pm
lib/SOAP/WSDL/Factory/Generator.pm
lib/SOAP/WSDL/Factory/Serializer.pm
lib/SOAP/WSDL/Factory/Transport.pm
lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm
lib/SOAP/WSDL/Generator/PrefixResolver.pm
lib/SOAP/WSDL/Generator/Template.pm
lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm
lib/SOAP/WSDL/Generator/Template/XSD.pm
lib/SOAP/WSDL/Generator/Template/XSD/_type_class.tt
lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt
@@ -102,13 +122,23 @@ lib/SOAP/WSDL/Generator/Template/XSD/complexType/complexContent.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/complexContent.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/content_model.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt
lib/SOAP/WSDL/Generator/Template/XSD/complexType/variety.tt
lib/SOAP/WSDL/Generator/Template/XSD/element.tt
lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt
lib/SOAP/WSDL/Generator/Template/XSD/element/POD/structure.tt
lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt
lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt
@@ -120,6 +150,7 @@ lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt
lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Operation.tt
lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Part.tt
lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Type.tt
lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt
lib/SOAP/WSDL/Generator/Template/XSD/Server.tt
lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Message.tt
lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/method_info.tt
@@ -129,16 +160,21 @@ lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/atomicType.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/structure.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt
lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt
lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt
lib/SOAP/WSDL/Generator/Visitor.pm
lib/SOAP/WSDL/Generator/Visitor/Typelib.pm
lib/SOAP/WSDL/Generator/Visitor/Typemap.pm
lib/SOAP/WSDL/Manual.pod
lib/SOAP/WSDL/Manual/CodeFirst.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
@@ -153,25 +189,42 @@ 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/Server/Simple.pm
lib/SOAP/WSDL/Service.pm
lib/SOAP/WSDL/SOAP/Address.pm
lib/SOAP/WSDL/SOAP/Body.pm
lib/SOAP/WSDL/SOAP/Header.pm
lib/SOAP/WSDL/SOAP/HeaderFault.pm
lib/SOAP/WSDL/SOAP/Operation.pm
lib/SOAP/WSDL/SOAP/Typelib/Fault.pm
lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
lib/SOAP/WSDL/Transport/HTTP.pm
lib/SOAP/WSDL/Transport/Loopback.pm
lib/SOAP/WSDL/Transport/Test.pm
lib/SOAP/WSDL/TypeLookup.pm
lib/SOAP/WSDL/Types.pm
lib/SOAP/WSDL/XSD/Annotation.pm
lib/SOAP/WSDL/XSD/Attribute.pm
lib/SOAP/WSDL/XSD/AttributeGroup.pm
lib/SOAP/WSDL/XSD/Builtin.pm
lib/SOAP/WSDL/XSD/ComplexType.pm
lib/SOAP/WSDL/XSD/Element.pm
lib/SOAP/WSDL/XSD/Enumeration.pm
lib/SOAP/WSDL/XSD/FractionDigits.pm
lib/SOAP/WSDL/XSD/Group.pm
lib/SOAP/WSDL/XSD/Length.pm
lib/SOAP/WSDL/XSD/MaxExclusive.pm
lib/SOAP/WSDL/XSD/MaxInclusive.pm
lib/SOAP/WSDL/XSD/MaxLength.pm
lib/SOAP/WSDL/XSD/MinExclusive.pm
lib/SOAP/WSDL/XSD/MinInclusive.pm
lib/SOAP/WSDL/XSD/MinLength.pm
lib/SOAP/WSDL/XSD/Pattern.pm
lib/SOAP/WSDL/XSD/Schema.pm
lib/SOAP/WSDL/XSD/Schema/Builtin.pm
lib/SOAP/WSDL/XSD/SimpleType.pm
lib/SOAP/WSDL/XSD/TotalDigits.pm
lib/SOAP/WSDL/XSD/Typelib/Attribute.pm
lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
@@ -224,27 +277,23 @@ lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm
lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
lib/SOAP/WSDL/XSD/Typelib/Element.pm
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
lib/SOAP/WSDL/XSD/WhiteSpace.pm
LICENSE
Makefile.PL
MANIFEST This list of files
META.yml
MIGRATING
patches/Manual.diff
README
t/001_use.t
t/002_parse_wsdl.t
t/003_wsdl_based_serializer.t
t/004_parse_wsdl.t
t/006_client.t
t/007_envelope.t
t/008_client_wsdl_complexType.t
t/009_data_classes.t
t/011_simpleType.t
t/012_element.t
t/013_complexType.t
t/016_client_object.t
t/017_generator.t
t/020_storable.t
t/094_cpan_meta.t
t/095_copying.t
t/096_characters.t
t/097_kwalitee.t
@@ -271,29 +320,44 @@ t/acceptance/wsdl/05_simpleType-restriction.wsdl
t/acceptance/wsdl/05_simpleType-union.wsdl
t/acceptance/wsdl/10_helloworld.asmx.xml
t/acceptance/wsdl/11_helloworld.wsdl
t/acceptance/wsdl/contributed/Axis.wsdl
t/acceptance/wsdl/contributed/ETest.wsdl
t/acceptance/wsdl/contributed/gasquery.wsdl
t/acceptance/wsdl/contributed/OITest.wsdl
t/acceptance/wsdl/contributed/tools.wsdl
t/acceptance/wsdl/elementAtomicComplexType.xml
t/acceptance/wsdl/email_account.wsdl
t/acceptance/wsdl/generator_test.wsdl
t/acceptance/wsdl/generator_test_dot_names.wsdl
t/acceptance/wsdl/generator_unsupported_test.wsdl
t/acceptance/wsdl/helloWorld_header.wsdl
t/acceptance/wsdl/import.xsd
t/acceptance/wsdl/import_loop.xsd
t/acceptance/wsdl/message_gateway.wsdl
t/acceptance/wsdl/nested_complextype.wsdl
t/acceptance/wsdl/WSDLParser-import.wsdl
t/acceptance/wsdl/WSDLParser-imported.wsdl
t/acceptance/wsdl/WSDLParser.wsdl
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/CodeFirst/ComplexType.pm
t/CodeFirst/element.pm
t/CodeFirst/sequence.pm
t/CodeFirst/test.pl
t/contributed.wsdl
t/Expat/03_wsdl.t
t/lib/CodeFirst.pm
t/lib/Mod_Perl2Test.pm
t/lib/MyComplexType.pm
t/lib/MyElement.pm
t/lib/MySimpleElement.pm
t/lib/MySimpleType.pm
t/lib/Test/SOAPMessage.pm
t/lib/Test/SOAP/WSDL/Expat/WSDLParser.pm
t/lib/Test/SOAP/WSDL/Generator/Iterator/WSDL11.pm
t/lib/Test/SOAP/WSDL/Generator/Visitor/Typemap.pm
t/lib/Test/SOAP/WSDL/Tester.pm
t/lib/Typelib/Base.pm
t/lib/Typelib/TEnqueueMessage.pm
t/lib/Typelib/TMessage.pm
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
@@ -311,8 +375,10 @@ t/SOAP/WSDL/05_simpleType-union.t
t/SOAP/WSDL/06_keep_alive.t
t/SOAP/WSDL/11_helloworld.NET.t
t/SOAP/WSDL/12_binding.t
t/SOAP/WSDL/Base.t
t/SOAP/WSDL/Client.t
t/SOAP/WSDL/Client/Base.t
t/SOAP/WSDL/Definitions.t
t/SOAP/WSDL/Deserializer/Hash.t
t/SOAP/WSDL/Deserializer/SOM.t
t/SOAP/WSDL/Deserializer/XSD.t
@@ -323,26 +389,37 @@ t/SOAP/WSDL/Factory/Deserializer.t
t/SOAP/WSDL/Factory/Serializer.t
t/SOAP/WSDL/Factory/Transport.t
t/SOAP/WSDL/Generator/Template.t
t/SOAP/WSDL/Generator/Template/XSD/Import.t
t/SOAP/WSDL/Generator/Template/XSD/Unqualified.t
t/SOAP/WSDL/Generator/Visitor.t
t/SOAP/WSDL/Generator/Visitor/Typemap.t
t/SOAP/WSDL/Generator/XCS.t
t/SOAP/WSDL/Generator/XSD.t
t/SOAP/WSDL/Generator/XSD_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
t/SOAP/WSDL/Part.t
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/Server/Simple.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
t/SOAP/WSDL/XSD/AttributeGroup.t
t/SOAP/WSDL/XSD/Builtin.t
t/SOAP/WSDL/XSD/ComplexType.t
t/SOAP/WSDL/XSD/Element.t
t/SOAP/WSDL/XSD/Enumeration.t
t/SOAP/WSDL/XSD/Schema.t
t/SOAP/WSDL/XSD/SimpleType.t
t/SOAP/WSDL/XSD/Typelib/Attribute.t
t/SOAP/WSDL/XSD/Typelib/Builtin/01_constructors.t
t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t
t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t
t/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.t
@@ -353,8 +430,14 @@ t/SOAP/WSDL/XSD/Typelib/Builtin/date.t
t/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.t
t/SOAP/WSDL/XSD/Typelib/Builtin/decimal.t
t/SOAP/WSDL/XSD/Typelib/Builtin/double.t
t/SOAP/WSDL/XSD/Typelib/Builtin/duration.t
t/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.t
t/SOAP/WSDL/XSD/Typelib/Builtin/float.t
t/SOAP/WSDL/XSD/Typelib/Builtin/gDay.t
t/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.t
t/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.t
t/SOAP/WSDL/XSD/Typelib/Builtin/gYear.t
t/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.t
t/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.t
t/SOAP/WSDL/XSD/Typelib/Builtin/ID.t
t/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.t
@@ -374,6 +457,7 @@ t/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.t
t/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.t
t/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.t
t/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.t
t/SOAP/WSDL/XSD/Typelib/Builtin/QName.t
t/SOAP/WSDL/XSD/Typelib/Builtin/short.t
t/SOAP/WSDL/XSD/Typelib/Builtin/string.t
t/SOAP/WSDL/XSD/Typelib/Builtin/time.t
@@ -391,4 +475,5 @@ t/SOAP/WSDL_NO_MESSAGE.wsdl
t/SOAP/WSDL_NO_PORTTYPE.wsdl
t/test.wsdl
TEST_COVERAGE
test_html.pl
TODO

281
META.yml
View File

@@ -1,281 +0,0 @@
---
name: SOAP-WSDL
version: 2.00_29
author:
- 'Martin Kutter <martin.kutter@fen-net.de>'
abstract: SOAP with WSDL support
license: artistic
resources:
license: http://opensource.org/licenses/artistic-license.php
requires:
Class::Std::Fast: !!perl/hash:version
original: v0.0.5
qv: 1
version:
- 0
- 0
- 5
Data::Dumper: 0
Date::Format: 0
Date::Parse: 0
File::Basename: 0
File::Path: 0
Getopt::Long: 0
LWP::UserAgent: 0
List::Util: 0
Template: 0
Term::ReadKey: 0
XML::Parser::Expat: 0
perl: 5.8.0
provides:
SOAP::WSDL:
file: lib/SOAP/WSDL.pm
version: 2.00_25
SOAP::WSDL::Base:
file: lib/SOAP/WSDL/Base.pm
version: 2.00_27
SOAP::WSDL::Binding:
file: lib/SOAP/WSDL/Binding.pm
SOAP::WSDL::Client:
file: lib/SOAP/WSDL/Client.pm
version: 2.00_27
SOAP::WSDL::Client::Base:
file: lib/SOAP/WSDL/Client/Base.pm
version: 2.00_25
SOAP::WSDL::Definitions:
file: lib/SOAP/WSDL/Definitions.pm
version: 2.00_27
SOAP::WSDL::Deserializer::Hash:
file: lib/SOAP/WSDL/Deserializer/Hash.pm
version: 2.00_25
SOAP::WSDL::Deserializer::SOM:
file: lib/SOAP/WSDL/Deserializer/SOM.pm
version: 2.00_24
SOAP::WSDL::Deserializer::XSD:
file: lib/SOAP/WSDL/Deserializer/XSD.pm
version: 2.00_25
SOAP::WSDL::Expat::Base:
file: lib/SOAP/WSDL/Expat/Base.pm
version: 2.00_27
SOAP::WSDL::Expat::Message2Hash:
file: lib/SOAP/WSDL/Expat/Message2Hash.pm
version: 2.00_27
SOAP::WSDL::Expat::MessageParser:
file: lib/SOAP/WSDL/Expat/MessageParser.pm
version: 2.00_27
SOAP::WSDL::Expat::MessageStreamParser:
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
version: 2.00_24
SOAP::WSDL::Factory::Deserializer:
file: lib/SOAP/WSDL/Factory/Deserializer.pm
version: 2.00_24
SOAP::WSDL::Factory::Generator:
file: lib/SOAP/WSDL/Factory/Generator.pm
version: 2.00_24
SOAP::WSDL::Factory::Serializer:
file: lib/SOAP/WSDL/Factory/Serializer.pm
version: 2.00_24
SOAP::WSDL::Factory::Transport:
file: lib/SOAP/WSDL/Factory/Transport.pm
version: 2.00_25
SOAP::WSDL::Generator::Template:
file: lib/SOAP/WSDL/Generator/Template.pm
version: 2.00_25
SOAP::WSDL::Generator::Template::XSD:
file: lib/SOAP/WSDL/Generator/Template/XSD.pm
version: 2.00_27
SOAP::WSDL::Generator::Visitor:
file: lib/SOAP/WSDL/Generator/Visitor.pm
version: 2.00_25
SOAP::WSDL::Generator::Visitor::Typelib:
file: lib/SOAP/WSDL/Generator/Visitor/Typelib.pm
SOAP::WSDL::Generator::Visitor::Typemap:
file: lib/SOAP/WSDL/Generator/Visitor/Typemap.pm
version: 2.00_25
SOAP::WSDL::Message:
file: lib/SOAP/WSDL/Message.pm
SOAP::WSDL::OpMessage:
file: lib/SOAP/WSDL/OpMessage.pm
SOAP::WSDL::Operation:
file: lib/SOAP/WSDL/Operation.pm
SOAP::WSDL::Part:
file: lib/SOAP/WSDL/Part.pm
SOAP::WSDL::Port:
file: lib/SOAP/WSDL/Port.pm
SOAP::WSDL::PortType:
file: lib/SOAP/WSDL/PortType.pm
SOAP::WSDL::SOAP::Address:
file: lib/SOAP/WSDL/SOAP/Address.pm
SOAP::WSDL::SOAP::Body:
file: lib/SOAP/WSDL/SOAP/Body.pm
SOAP::WSDL::SOAP::Header:
file: lib/SOAP/WSDL/SOAP/Header.pm
SOAP::WSDL::SOAP::HeaderFault:
file: lib/SOAP/WSDL/SOAP/HeaderFault.pm
SOAP::WSDL::SOAP::Operation:
file: lib/SOAP/WSDL/SOAP/Operation.pm
version: 2.00_25
SOAP::WSDL::SOAP::Typelib::Fault11:
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
version: 2.00_25
SOAP::WSDL::Serializer::XSD:
file: lib/SOAP/WSDL/Serializer/XSD.pm
version: 2.00_27
SOAP::WSDL::Server:
file: lib/SOAP/WSDL/Server.pm
version: 2.00_27
SOAP::WSDL::Server::CGI:
file: lib/SOAP/WSDL/Server/CGI.pm
version: 2.00_27
SOAP::WSDL::Service:
file: lib/SOAP/WSDL/Service.pm
SOAP::WSDL::Transport::HTTP:
file: lib/SOAP/WSDL/Transport/HTTP.pm
SOAP::WSDL::Transport::Loopback:
file: lib/SOAP/WSDL/Transport/Loopback.pm
version: 2.00_25
SOAP::WSDL::Transport::Test:
file: lib/SOAP/WSDL/Transport/Test.pm
version: 2.00_25
SOAP::WSDL::TypeLookup:
file: lib/SOAP/WSDL/TypeLookup.pm
version: 2.00_29
SOAP::WSDL::Types:
file: lib/SOAP/WSDL/Types.pm
SOAP::WSDL::XSD::Attribute:
file: lib/SOAP/WSDL/XSD/Attribute.pm
version: 2.00_29
SOAP::WSDL::XSD::Builtin:
file: lib/SOAP/WSDL/XSD/Builtin.pm
SOAP::WSDL::XSD::ComplexType:
file: lib/SOAP/WSDL/XSD/ComplexType.pm
version: 2.00_25
SOAP::WSDL::XSD::Element:
file: lib/SOAP/WSDL/XSD/Element.pm
version: 2.00_25
SOAP::WSDL::XSD::Schema:
file: lib/SOAP/WSDL/XSD/Schema.pm
version: 2.00_25
SOAP::WSDL::XSD::Schema::Builtin:
file: lib/SOAP/WSDL/XSD/Schema/Builtin.pm
SOAP::WSDL::XSD::SimpleType:
file: lib/SOAP/WSDL/XSD/SimpleType.pm
version: 2.00_25
SOAP::WSDL::XSD::Typelib::Attribute:
file: lib/SOAP/WSDL/XSD/Typelib/Attribute.pm
SOAP::WSDL::XSD::Typelib::AttributeSet:
file: lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm
SOAP::WSDL::XSD::Typelib::Builtin:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
version: 2.00_25
SOAP::WSDL::XSD::Typelib::Builtin::ENTITY:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm
SOAP::WSDL::XSD::Typelib::Builtin::ID:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm
SOAP::WSDL::XSD::Typelib::Builtin::IDREF:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm
SOAP::WSDL::XSD::Typelib::Builtin::IDREFS:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm
SOAP::WSDL::XSD::Typelib::Builtin::NCName:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm
SOAP::WSDL::XSD::Typelib::Builtin::NOTATION:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm
SOAP::WSDL::XSD::Typelib::Builtin::Name:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm
SOAP::WSDL::XSD::Typelib::Builtin::QName:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm
SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm
SOAP::WSDL::XSD::Typelib::Builtin::anyType:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm
version: 2.00_29
SOAP::WSDL::XSD::Typelib::Builtin::anyURI:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm
SOAP::WSDL::XSD::Typelib::Builtin::base64Binary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm
SOAP::WSDL::XSD::Typelib::Builtin::boolean:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm
version: 2.00_23
SOAP::WSDL::XSD::Typelib::Builtin::byte:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm
SOAP::WSDL::XSD::Typelib::Builtin::date:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm
SOAP::WSDL::XSD::Typelib::Builtin::dateTime:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm
SOAP::WSDL::XSD::Typelib::Builtin::decimal:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm
SOAP::WSDL::XSD::Typelib::Builtin::double:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm
SOAP::WSDL::XSD::Typelib::Builtin::duration:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm
SOAP::WSDL::XSD::Typelib::Builtin::float:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm
SOAP::WSDL::XSD::Typelib::Builtin::gDay:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm
SOAP::WSDL::XSD::Typelib::Builtin::gMonth:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm
SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm
SOAP::WSDL::XSD::Typelib::Builtin::gYear:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm
SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm
SOAP::WSDL::XSD::Typelib::Builtin::hexBinary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm
SOAP::WSDL::XSD::Typelib::Builtin::int:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm
SOAP::WSDL::XSD::Typelib::Builtin::integer:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm
SOAP::WSDL::XSD::Typelib::Builtin::language:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm
SOAP::WSDL::XSD::Typelib::Builtin::list:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm
SOAP::WSDL::XSD::Typelib::Builtin::long:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm
SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::normalizedString:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm
SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::short:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm
SOAP::WSDL::XSD::Typelib::Builtin::string:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm
SOAP::WSDL::XSD::Typelib::Builtin::time:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm
version: 2.00_25
SOAP::WSDL::XSD::Typelib::Builtin::token:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm
SOAP::WSDL::XSD::Typelib::ComplexType:
file: lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
version: 2.00_29
SOAP::WSDL::XSD::Typelib::Element:
file: lib/SOAP/WSDL/XSD/Typelib/Element.pm
version: 2.00_29
SOAP::WSDL::XSD::Typelib::SimpleType:
file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
SOAP::WSDL::XSD::Typelib::SimpleType::restriction:
file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
generated_by: Module::Build version 0.2808
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.2.html
version: 1.2
no_index:
directory: lib/SOAP/WSDL/Generator/Template/XSD/

View File

@@ -1,7 +1,36 @@
MIGRATING
---------
MIGRATING FROM PRE-2.00_33
--------------------------
The handling of stringification of SOAP::WSDL::XSD simpleType objects with
undef values changed in 2.00_33.
This document describes how to migrate from 2.00_24 and before versions to
While 2.00_32 and before returned undef on stringification of a undef value,
>=2.00_33 now returns an empty string.
This is due to common usage in templates or the like, where undef is likely
to produce a warning, and the unreliable behavior of
$obj eq undef
which behaves differently in different versions of perl.
MIGRATING FROM PRE-2.00_29
--------------------------
SOAP::WSDL 2.00_29 added experimental XML attribute support. The attribute
support changed the code of the generated classes, which may now
require the class SOAP::WSDL::XSD::Typelib::Attribute introduced in the same
pre-release.
While interfaces generated with pre-releases back to 2.00_25 work without
change, this does not hold true vice versa: Interfaces generated with
2.00_29 and above won't work with older pre-releases.
You'll have to update SOAP::WSDL on all your machines.
MIGRATING FROM PRE-2.00_24
--------------------------
This section describes how to migrate from 2.00_24 and before versions to
2.00_25.
Migrating from 2.00_xx
@@ -9,9 +38,9 @@ Migrating from 2.00_xx
Background
SOAP::WSDL 2.00_xx has used Class::Std as base for its inside out objects
SOAP::WSDL 2.00_xx has used Class::Std as base for its inside out objects
up to 2.00_24. For performance reasons, now Class::Std::Fast is used.
As Class::Std::Fast is a drop-in replacement for Class::Std, there should be
As Class::Std::Fast is a drop-in replacement for Class::Std, there should be
no need to change anything in your (handwritten) code.
Generated interfaces
@@ -26,8 +55,8 @@ Typemaps
SOAP::WSDL now tries to load all typemap classes at once from 2.00_25 on.
If you use __SKIP__ in your typemaps, you'll have to comment out all
path deeper than the path marked with __SKIP__ - if you don't, SOAP::WSDL
If you use __SKIP__ in your typemaps, you'll have to comment out all
paths deeper than the path marked with __SKIP__ - if you don't, SOAP::WSDL
will try to load all correspondent classes.
Migrating from 1.xx
@@ -39,7 +68,7 @@ SOAP::WSDL uses a custom WSDL parser and serializer. It does not rely on XPath
for on the fly WSDL processing, nor does it use SOAP::Data objects for
encoding any more.
You should be able to use your wxisting code under most circumstances.
You should be able to use your existing code under most circumstances.
SOAP::WSDL is the compatibility module for old interfaces.
Overloading

View File

@@ -1,31 +1,44 @@
# Note: this file was auto-generated by Module::Build::Compat version 0.03
unless (eval "use Module::Build::Compat 0.02; 1" ) {
print "This module requires Module::Build to install itself.\n";
require ExtUtils::MakeMaker;
my $yn = ExtUtils::MakeMaker::prompt
(' Install Module::Build now from CPAN?', 'y');
unless ($yn =~ /^y/i) {
die " *** Cannot install without Module::Build. Exiting ...\n";
}
require Cwd;
require File::Spec;
require CPAN;
# Save this 'cause CPAN will chdir all over the place.
my $cwd = Cwd::cwd();
CPAN::Shell->install('Module::Build::Compat');
CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
or die "Couldn't install Module::Build, giving up.\n";
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
}
eval "use Module::Build::Compat 0.02; 1" or die $@;
Module::Build::Compat->run_build_pl(args => \@ARGV);
require Module::Build;
Module::Build::Compat->write_makefile(build_class => 'Module::Build');
use 5.010000;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'SOAP::WSDL',
VERSION_FROM => 'lib/SOAP/WSDL.pm',
PREREQ_PM => {
'Class::Std::Fast' => q(0.000005),
'Cwd' => 0,
'Data::Dumper' => 0,
'Date::Format' => 0,
'Date::Parse' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'File::Spec' => 0,
'Getopt::Long' => 0,
'LWP::UserAgent' => 0,
'List::Util' => 0,
'Module::Build' => 0,
'Storable' => 0,
'Template' => q(2.18),
'Term::ReadKey' => 0,
'Test::More' => 0,
'URI' => 0,
'XML::Parser::Expat' => 0,
'Class::Load' => 0.20,
'perl' => q(5.008),
},
test => { RECURSIVE_TEST_FILES => 1, },
ABSTRACT_FROM => 'lib/SOAP/WSDL.pm',
AUTHOR => 'Scott Walters <scott@slowass.net>',
(eval { ExtUtils::MakeMaker->VERSION(6.46) } ? (META_MERGE => {
'meta-spec' => { version => 2 },
resources => {
repository => {
type => 'git',
url => 'https://github.com/scrottie/SOAP-WSDL.git',
web => 'https://github.com/scrottie/SOAP-WSDL',
},
}})
: ()
),
);

37
README
View File

@@ -3,7 +3,25 @@ INTRO
SOAP-WSDL provides a SOAP client with WSDL support.
This is a developer release - everything may (and most things will) change.
SUBCLASSING
-----------
SOAP-WSDL is still under very active development. Please don't build
applications using the following modules directly:
- SOAP::WSDL::Definitions
- SOAP::WSDL::Port
- SOAP::WSDL::PortType
- SOAP::WSDL::Binding
- SOAP::WSDL::Message
- SOAP::WSDL::Operation
- SOAP::WSDL::OpMessage
- SOAP::WSDL::Part
- SOAP::WSDL::Service
- SOAP::WSDL::Types
- SOAP::WSDL::XSD::Schema
Those will be replaced some time in the future.
INSTALLING
----------
@@ -15,12 +33,21 @@ Use the following mantra:
perl Build test
perl Build install
If you don't have Module::Build installed, you may also use
If you don't have Module::Build installed, you may also use
perl Makefile.PL
make
make
make test
make install
Note that Module::Build is the recommended installer - make will not run
all tests provided with SOAP-WSDL.
Note that Module::Build is the recommended installer - make will not run
all tests provided with SOAP-WSDL.
SOLARIS INSTALLATION NOTES
--------------------------
According to a CPAN RT report http://rt.cpan.org/Ticket/Display.html?id=36865
it may be necessary to check (and possibly update) the expat libraries
required by XML::Parser.
SOAP::WSDL's metadata includes XML::Parser, but it seems that the expat
libraries XML::Parser depends on may slip through missing or outdated.

View File

@@ -1,11 +1,25 @@
# 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
#
perl Build.PL && perl Build && \
perl -MTAP::Harness -MFile::Find::Rule -e '
local $ENV{TEST_VERBOSE} = 1;
TAP::Harness->new({
merge => 1,
lib => [ q{t/lib}, q{blib/lib} ],
switches => [ q{-MDevel::Cover=-ignore,.,-select,^blib/lib/.+,-coverage,statement,-coverage,subroutine,-coverage,condition,-coverage,branch} ],
})->runtests( sort { $a cmp $b } File::Find::Rule->file()->name( q{*.t} )->in( q{t/} ) );
'
cd t/
# Devel::CoverX::Covered
# covered runs
find . -type f -name '*.t' | xargs -n 1 /usr/bin/perl -MDevel::Cover=-silent,1,-summary,0 -I../lib
cover
cover -ignore_re \.t$ -ignore_re ^lib -coverage="statement" -coverage=condition -coverage=subroutine -coverage="branch"
# cover -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)

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

@@ -0,0 +1,35 @@
use Benchmark qw(cmpthese timethis timethese);
use POSIX ();
use Date::Format ();
my @time_from = localtime;
#use lib '../../lib';
use SOAP::WSDL::XSD::Typelib::Builtin::dateTime;
my $date = SOAP::WSDL::XSD::Typelib::Builtin::dateTime->new();
timethese 10000, {
'sprintf' => sub { $date->set_value('Dec 24 2004 CET'); }
};
__END__
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,44 @@
#!/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::SOAP11;
use XML::Compile::WSDL11;
use XML::Compile::Transport::SOAPHTTP;
use MyInterfaces::HelloWorld::HelloWorldSoap;
use SOAP::WSDL::Deserializer::XSD_XS;
use Benchmark qw(cmpthese);
#use SOAP::WSDL::Deserializer::XSD_XS;
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();
$soap_xs->set_deserializer( SOAP::WSDL::Deserializer::XSD_XS->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 +55,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 +78,16 @@ sub lite_bench {
);
}
# give all a chance to perform first-run initializations
compile_bench();
lite_bench();
wsdl_bench();
wsdl_xs_bench();
#wsdl_xs_bench();
cmpthese 150, {
timethese 150, {
'SOAP::WSDL' => \&wsdl_bench,
'SOAP::WSDL_XS' => \&wsdl_xs_bench,
# 'SOAP::WSDL_XS' => \&wsdl_xs_bench,
'XML::Compile' => \&compile_bench,
# 'SOAP::Lite' => \&lite_bench,
}
'SOAP::Lite' => \&lite_bench,
};

View File

@@ -1,31 +1,99 @@
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;
use Benchmark qw(cmpthese);
use XML::Compile::SOAP11;
use XML::Compile::Transport::SOAPHTTP();
use XML::Compile::Util;
use XML::Compile::WSDL11;
use XML::Simple;
use SOAP::WSDL::Deserializer::XSD_XS;
use SOAP::WSDL::Factory::Deserializer;
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
use SOAP::Lite;
use MyInterfaces::TestService::TestPort;
my $compile = XML::Compile::WSDL11->new('../example/wsdl/Person.wsdl');
#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';
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,
validation => 0,
ignore_facets => 1,
);
#
# Call all variants once to allow their first-time tasks to be done
#
my $call = $compile->compileClient('ListPerson');
$call->({ in => undef});
# Initialize SOAP::Lite
my $deserializer = SOAP::Deserializer->new();
# Initialize SOAP::WSDL interface
my $soap = MyInterfaces::TestService::TestPort->new();
# Load all classes - XML::Compile has created everything before, too
@@ -35,12 +103,20 @@ my $lite = SOAP::Lite->new()->default_ns('http://www.example.org/benchmark/')
->proxy('http://localhost:81/soap-wsdl-test/person.pl');
$lite->on_action( sub { 'http://www.example.org/benchmark/ListPerson' } );
# # register for SOAP 1.1
SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' );
my $wsdl_xs = MyInterfaces::TestService::TestPort->new();
$lite->ListPerson();
# trigger loading of XML Data
my $count = 100;
my $lite_xml = SOAP::Lite->new()->default_ns('http://www.example.org/benchmark/')
->proxy('http://localhost:81/soap-wsdl-test/person.pl');
$lite_xml->on_action( sub { 'http://www.example.org/benchmark/ListPerson' } );
$lite_xml->outputxml(1);
$lite_xml->ListPerson();
# # register for SOAP 1.1
#SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' );
#my $wsdl_xs = MyInterfaces::TestService::TestPort->new();
my $count = 70;
my @data = ();
my $n = 0;
print "Benchmark conducted with
@@ -48,39 +124,60 @@ SOAP::Lite - $SOAP::Lite::VERSION
SOAP::WSDL - $SOAP::WSDL::Client::VERSION
SOAP::WSDL_XS - $SOAP::WSDL::Deserializer::XSD_XS::VERSION;
XML::Compile::SOAP - $XML::Compile::SOAP::VERSION
XML::Simple - $XML::Simple::VERSION
XML::Simple uses XML::Parser as backend and SOAP::Lite with
outputxml(1) set as SOAP client.
XML::Parser - $XML::Parser::VERSION
XML::Simple is not benchmarked in run 3ff, as it is expected
do deliver the same result.
Benchmark $n: Store result in private variable and destroy it
";
$n++;
cmpthese $count, {
# 'XML::Simple' => sub { my $result = XMLin( MyData::xml() )},
'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) },
'XML::Compile' => sub { my $result = $call->() },
'SOAP::WSDL_XS' => sub { my $result = $wsdl_xs->ListPerson({}) },
# 'SOAP::Lite' => sub { my $result = $deserializer->deserialize( MyData::xml() )},
'SOAP::Lite' => sub { my $som = $lite->call('ListPerson') },
'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) },
# 'SOAP::WSDL_XS' => sub { my $result = $wsdl_xs->ListPerson({}) },
'XML::Compile' => sub { my $result = $call->() },
'XML::Simple' => sub { my $result = XMLin( $lite_xml->call('ListPerson')) },
};
print "\nBenchmark $n: Push result on list\n";
$n++;
cmpthese $count, {
# 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )},
'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
'XML::Compile' => sub { push @data, $call->() },
'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) },
# 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )}
'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
# 'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) },
'XML::Compile' => sub { push @data, $call->() },
'XML::Simple' => sub { push @data, XMLin( $lite_xml->call('ListPerson')) },
};
@data = ();
print "\nBenchmark $n: Play it again, Sam\n";
print "\nBenchmark $n: Play it, please 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_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') },
'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, $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

@@ -0,0 +1,19 @@
use lib '../lib';
use lib '../example/lib';
use lib '../../SOAP-WSDL_XS/blib/lib';
use lib '../../SOAP-WSDL_XS/blib/arch';
use strict;
# use Benchmark;
use SOAP::WSDL::Deserializer::XSD_XS;
use SOAP::WSDL::Factory::Deserializer;
# # register for SOAP 1.1
SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' );
use MyInterfaces::TestService::TestPort;
my $soap = MyInterfaces::TestService::TestPort->new();
# Load all classes - XML::Compile has created everything before, too
if (@ARGV) { print $soap->ListPerson({}) }
else {
$soap->ListPerson({})
}

File diff suppressed because one or more lines are too long

View File

@@ -10,23 +10,26 @@ use Term::ReadKey;
my %opt = (
url => '',
prefix => undef,
type_prefix => 'MyTypes',
element_prefix => 'MyElements',
typemap_prefix => 'MyTypemaps',
interface_prefix => 'MyInterfaces',
prefix => 'My',
attribute_prefix => undef,
type_prefix => undef,
element_prefix => undef,
typemap_prefix => undef,
interface_prefix => undef,
server_prefix => undef,
base_path => 'lib/',
proxy => undef,
generator => 'XSD',
server => 0,
namespace => 0,
);
{ # a block just to scope "no warnings"
no warnings qw(redefine);
*LWP::UserAgent::get_basic_credentials = sub {
my ($user, $password);
# remove user from option if called, to force prompting for a user
# remove user from option if called, to force prompting for a user
# name the next time
print "URL requires authorization.\n";
if (not $user = delete $opt{user}) {
@@ -34,24 +37,28 @@ my %opt = (
ReadMode 1;
$user = ReadLine();
ReadMode 0;
chomp $user;
};
if (not $password = delete $opt{password}) {
print 'Password:';
ReadMode 2;
$user = ReadLine;
ReadMode 0;
$password = ReadLine;
ReadMode 0;
chomp $password;
};
return ($user, $password);
};
};
}
GetOptions(\%opt,
qw(
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
@@ -60,7 +67,8 @@ GetOptions(\%opt,
user=s
password=s
generator=s
server
server|s
namespaces|n
)
);
@@ -69,24 +77,36 @@ my $url = $ARGV[0];
pod2usage( -exit => 1 , verbose => 2 ) if ($opt{help});
pod2usage( -exit => 1 , verbose => 1 ) if not ($url);
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy};
local $ENV{HTTPS_PROXY} = $opt{proxy} if $opt{proxy};
my $lwp = LWP::UserAgent->new(
$opt{keep_alive}
? ( keep_alive => 1 )
my $lwp = LWP::UserAgent->new(
$opt{keep_alive}
? ( keep_alive => 1 )
: ()
);
$lwp->env_proxy(); # get proxy from environment. Works for both http & https.
$lwp->agent(qq[SOAP::WSDL $SOAP::WSDL::Expat::WSDLParser::VERSION]);
my $response = $lwp->get($url);
die $response->message(), "\n" if $response->code != 200;
my $parser = SOAP::WSDL::Expat::WSDLParser->new({
user_agent => $lwp,
});
my $xml = $response->content();
# resolve the default prefix options
map {
my $opt_key = $_;
if ( $opt_key =~ / (\w+) _prefix $/xms # relevant option
&& !$opt{ $opt_key } # that hasn't already been explicitly set
)
{
my $prefix_type = $1;
$opt{ $opt_key } = $opt{prefix} . # My
ucfirst( $prefix_type ) . # Typemap
( $prefix_type eq 'server' ? '' : 's' ); # s
}
} keys %opt;
my $definitions = $parser->parse_string( $xml );
my $definitions = $parser->parse_uri( $url );
my %typemap = ();
@@ -106,13 +126,23 @@ 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_wsdl($xml) if $generator->can('set_wsdl');
$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...
$generator->generate();
@@ -135,34 +165,40 @@ wsdl2perl.pl - create perl bindings for SOAP webservices.
NAME SHORT DESCRITPION
----------------------------------------------------------------------------
prefix p Prefix for both type and element classes.
type_prefix t Prefix for type classes.
prefix p Prefix for all generated classes. If you set "-p=Foo",
you will get "FooAttributes", "FooTypes",
"FooElements" and so on.
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.
element_prefix e Prefix for element classes.
Default: MyElements
typemap_prefix m Prefix for typemap classes.
typemap_prefix m Prefix for typemap classes.
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
typemap_include mi File to include in typemap. Must eval() to a valid
perl hash (not a hash ref !).
proxy x HTTP(S) proxy to use (if any). wsdl2perl will also
proxy x HTTP(S) proxy to use (if any). wsdl2perl will also
use the proxy settings specified via the HTTP_PROXY
and HTTPS_PROXY environment variables.
keep_alive Use http keep_alive.
user Username for HTTP authentication
password Password. wsdl2perl will prompt if not given.
generator g Generator to use.
Default: XSD
generator g Generator to use.
Default: XSD
server s Generate a server interface (currently only CGI
supported)
help h Show help content
=head1 DESCRIPTION
Generates a interface class for a SOAP web service described by a WSDL
Generates a interface class for a SOAP web service described by a WSDL
definition.
The following classes are created:
@@ -171,7 +207,7 @@ The following classes are created:
=item * A interface class for every SOAP port in service
Interface classes are what you will mainly deal with: They provide a method
Interface classes are what you will mainly deal with: They provide a method
for accessing every web service method.
If you chose to generate Server interfaces, a class for every SOAP port in
@@ -183,13 +219,13 @@ to dispatch calls to.
=item * A typemap for every service
Typemaps are used internally by SOAP::WSDL for parsing the SOAP message into
object trees.
Typemaps are used internally by SOAP::WSDL for parsing the SOAP message into
object trees.
If the WSDL definition is incomplete, you may need to add some lines to
If the WSDL definition is incomplete, you may need to add some lines to
your typemap. Especially definitions for faults are sometimes left out.
Additional typemap content may be included by passing a file name as
Additional typemap content may be included by passing a file name as
typemap_include (mi) option.
=item * A type class for every element, complexType or simpleType definition
@@ -197,7 +233,7 @@ typemap_include (mi) option.
You may need to write additional type classes if your WSDL is incomplete.
For writing your own lib classes, see L<SOAP::WSDL::XSD::Typelib::Element>,
L<SOAP::WSDL::XSD::Typelib::ComplexType>
L<SOAP::WSDL::XSD::Typelib::ComplexType>
and L<SOAP::WSDL::XSD::Typelib::SimpleType>.
=back
@@ -210,26 +246,26 @@ You need Crypt::SSLeay installed for accessing HTTPS URLs.
=head2 Accessing protected documents
Use the -u option for specifying the user name. You will be prompted for a
password.
Use the -u option for specifying the user name. You will be prompted for a
password.
Alternatively, you may specify a passowrd with --password on the command
Alternatively, you may specify a passowrd with --password on the command
line.
=head2 Accessing documents protected by NTLM authentication
Set the --keep_alive option.
Note that accessing documents protected by NTLM authentication is currently
Note that accessing documents protected by NTLM authentication is currently
untested, because I have no access to a system using NTLM authentication.
If you try it, I would be glad if you could just drop me a note about
success or failure.
If you try it, I would be glad if you could just drop me a note about
success or failure.
=head1 LICENSE
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR

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

@@ -2,7 +2,7 @@
package main;
use strict;
use warnings;
#use lib qw(../lib ../../lib);
use lib qw(../lib ../../lib);
use MyElements::ListPersonResponse;
use MyServer::TestService::TestPort;
my $server = MyServer::TestService::TestPort->new({

View File

@@ -7,7 +7,9 @@ use lib 'lib'; # just needed because interface lies here
use MyInterfaces::HelloWorld::HelloWorldSoap;
# I instantiate a interface class.
my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new();
my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new({
# proxy => 'http://localhost:8080/JLearn/WS/sayHello'
});
# I have to lookup the method and synopsis from the interface's pod
my $result = $soap->sayHello({

View File

@@ -1,18 +1,21 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use XML::Compile::SOAP11;
use XML::Compile::WSDL11;
use XML::Compile::Transport::SOAPHTTP;
# I need access to the WSDL around - or use Data::Dumper::Streamer
# I need access to the WSDL around - or use Data::Dumper::Streamer
# for serializing the generated closures into (big) perl files
my $wsdl = XML::Compile::WSDL11->new('wsdl/11_helloworld.wsdl');
# I compile a interface method for a single SOAP method from the WSDL
# I have to lookup the method names from the WSDL
# or use the provided script examining the WSDL
my $call = $wsdl->compileClient('sayHello');
# I have to lookup the parameters from the WSDL - can be quite tricky
# XML::Compile provides a script creating examples, so I can use that, too.
my $result = $call->(
name => $ARGV[1] || '"Your name"',
givenName => $ARGV[0] || '"Your given name"',
@@ -22,4 +25,5 @@ my $result = $call->(
die "Error calling soap method" if not defined $result;
# I have to lookup the output parameters from the WSDL - or try Data::Dumper
# XML::Compile provides a script creating examples, so I can use that, too.
print $result->{ parameters }->{ sayHelloResult }, "\n";

View File

@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#use strict;
use warnings;
use SOAP::Lite +trace;
use SOAP::Lite; # +trace;
# I have to lookup the URL from the WSDL
my $soap = SOAP::Lite->new(

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-6-openjdk"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,5 @@
#Fri Feb 20 19:27:55 CET 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.source=1.5

View File

@@ -0,0 +1,8 @@
#Fri Feb 20 19:27:52 CET 2009
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
includeModules=false
resolveWorkspaceProjects=true
resourceFilterGoals=process-resources resources\:testResources
version=1

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HelloWorld"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="urn:HelloWorld"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema elementFormDefault="qualified"
targetNamespace="urn:HelloWorld">
<s:element name="sayHello">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1"
name="givenName" type="s:string" nillable="1" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="sayHelloResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="sayHelloResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="test2">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="name"
type="s:string" />
<s:element minOccurs="0" maxOccurs="1"
name="givenName" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="testExtended">
<s:extension base="s0:test2">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="extend" type="s:string" />
</s:sequence>
</s:extension>
</s:complexType>
</s:schema>
</types>
<message name="sayHelloSoapIn">
<part name="parameters" element="s0:sayHello" />
</message>
<message name="sayHelloSoapOut">
<part name="parameters" element="s0:sayHelloResponse" />
</message>
<portType name="Service1Soap">
<operation name="sayHello">
<input message="s0:sayHelloSoapIn" />
<output message="s0:sayHelloSoapOut" />
</operation>
</portType>
<binding name="Service1Soap" type="s0:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="sayHello">
<soap:operation soapAction="urn:HelloWorld#sayHello"
style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="HelloWorld">
<port name="HelloWorldSoap" binding="s0:Service1Soap">
<soap:address
location="http://localhost:81/soap-wsdl-test/helloworld.pl" />
</port>
</service>
</definitions>

22
example/java/cxf/README Normal file
View File

@@ -0,0 +1,22 @@
README
------
This is an example for creating a Apache CXF based client for a SOAP::WSDL
based SOAP server.
The example contains a pom.xml for building CXF based SOAP Clients from
a WSDL, a test Spring context configuration, and a JUnit4 test class for
testing the generated client.
It is intended to run against the HTTP::Server::Simple based SOAP server
in example/server/hello_simple.pl
To run the example, fire up the test server by calling
perl example/server/hello_simple.pl
Then open a second terminal and run
mvn test
The included JUnit test should pass.

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
>
<bindings
node="wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='urn:HelloWorld']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<jxb:serializable/>
</jxb:globalBindings>
</bindings>
</bindings>

181
example/java/cxf/pom.xml Normal file
View File

@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>perl.soap.wsdl</groupId>
<artifactId>cxf-test</artifactId>
<version>1.0.0</version>
<properties>
<cxf.version>2.1.4</cxf.version>
</properties>
<dependencies>
<!--
Depending on your requirements you may need more or fewer modules
from cxf
--><!--
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-common-utilities</artifactId>
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-web</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
<version>2.5.6.A</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.beans</artifactId>
<version>2.5.6.A</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.test</artifactId>
<version>2.5.6.A</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
<version>2.5.6.A</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
<version>2.5.6.A</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.0.9</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/11_helloworld.wsdl</wsdl>
<extraargs>
<extraarg>-b</extraarg>
<extraarg>${basedir}/jax-binding.xml</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,21 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
This http-conf:conduit is required for SOAP::WSDL based CGI-servers.
SOAP::WSDL::Server::CGI does not allow chunked transfer-encoding, which
is the default for CXF. the http-conf:conduit below switches it off.
Adapt the name to your URI(s). Wildcards are allowed.
-->
<http-conf:conduit
name="http://localhost:8081.http-conduit">
<http-conf:client AllowChunking="false"/>
</http-conf:conduit>
</beans>

View File

@@ -0,0 +1,38 @@
package helloworld;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
// Spring JUnit Test runner
@RunWith(SpringJUnit4ClassRunner.class)
// load spring context from here
@ContextConfiguration(locations = { "classpath:test-context.xml"})
/** Test class for the HelloWorld service
*
* It's more of a integration test, not a Unit test (though using
* JUnit4).
*
* Fire up the SOAP server in example/server/hello_simple.pl before
* running - the test will fail if it can't find the appropriate SOAP server
* at http://localhost:8081/
*
*/
public class HelloWorldTest {
// soapClient bean automatically provided by spring
@Autowired
private Service1Soap soapClient;
@Test
public void testClient() {
assertNotNull(soapClient);
String result = soapClient.sayHello("Kutter", "Martin");
assertEquals("Hello Martin Kutter", result);
}
}

View File

@@ -0,0 +1,16 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="helloworld.Service1Soap"/>
<property name="address" value="http://localhost:8081"/>
</bean>
<bean id="helloWorldClient" class="helloworld.Service1Soap"
factory-bean="proxyFactory" factory-method="create"/>
</beans>

View File

@@ -1,3 +1,4 @@
package MyElements::CountCookies;
use strict;
use warnings;
@@ -17,13 +18,30 @@ use base qw(
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
# There's no variety - empty complexType
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
__PACKAGE__->_factory();
} # end of BLOCK
1;
# __END__
=pod
@@ -36,6 +54,21 @@ MyElements::CountCookies
Perl data type class for the XML Schema defined element
CountCookies from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::CountCookiesResponse;
use strict;
use warnings;
@@ -16,6 +17,14 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
@@ -26,14 +35,18 @@ Class::Std::initialize();
my %CountCookiesResult_of :ATTR(:get<CountCookiesResult>);
__PACKAGE__->_factory(
[ qw(
CountCookiesResult
[ qw( CountCookiesResult
) ],
{
CountCookiesResult => \%CountCookiesResult_of,
'CountCookiesResult' => \%CountCookiesResult_of,
},
{
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
'CountCookiesResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
},
{
'CountCookiesResult' => 'CountCookiesResult',
}
);
@@ -44,11 +57,12 @@ __PACKAGE__->_factory(
} # end of BLOCK
1;
# __END__
=pod
@@ -61,6 +75,30 @@ MyElements::CountCookiesResponse
Perl data type class for the XML Schema defined element
CountCookiesResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=item * CountCookiesResult
$element->set_CountCookiesResult($data);
$element->get_CountCookiesResult();
=back
=head1 METHODS
=head2 new

View File

@@ -43,12 +43,6 @@ __PACKAGE__->_factory(
} # end BLOCK
} # end of BLOCK
1;

View File

@@ -1,3 +1,4 @@
package MyElements::GetFortuneCookie;
use strict;
use warnings;
@@ -17,13 +18,30 @@ use base qw(
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
# There's no variety - empty complexType
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
__PACKAGE__->_factory();
} # end of BLOCK
1;
# __END__
=pod
@@ -36,6 +54,21 @@ MyElements::GetFortuneCookie
Perl data type class for the XML Schema defined element
GetFortuneCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::GetFortuneCookieResponse;
use strict;
use warnings;
@@ -16,6 +17,14 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
@@ -26,14 +35,18 @@ Class::Std::initialize();
my %GetFortuneCookieResult_of :ATTR(:get<GetFortuneCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetFortuneCookieResult
[ qw( GetFortuneCookieResult
) ],
{
GetFortuneCookieResult => \%GetFortuneCookieResult_of,
'GetFortuneCookieResult' => \%GetFortuneCookieResult_of,
},
{
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'GetFortuneCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
},
{
'GetFortuneCookieResult' => 'GetFortuneCookieResult',
}
);
@@ -44,11 +57,12 @@ __PACKAGE__->_factory(
} # end of BLOCK
1;
# __END__
=pod
@@ -61,6 +75,30 @@ MyElements::GetFortuneCookieResponse
Perl data type class for the XML Schema defined element
GetFortuneCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=item * GetFortuneCookieResult
$element->set_GetFortuneCookieResult($data);
$element->get_GetFortuneCookieResult();
=back
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::GetSpecificCookie;
use strict;
use warnings;
@@ -16,6 +17,14 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
@@ -26,14 +35,18 @@ Class::Std::initialize();
my %index_of :ATTR(:get<index>);
__PACKAGE__->_factory(
[ qw(
index
[ qw( index
) ],
{
index => \%index_of,
'index' => \%index_of,
},
{
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
'index' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
},
{
'index' => 'index',
}
);
@@ -44,11 +57,12 @@ __PACKAGE__->_factory(
} # end of BLOCK
1;
# __END__
=pod
@@ -61,6 +75,30 @@ MyElements::GetSpecificCookie
Perl data type class for the XML Schema defined element
GetSpecificCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=item * index
$element->set_index($data);
$element->get_index();
=back
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::GetSpecificCookieResponse;
use strict;
use warnings;
@@ -16,6 +17,14 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
@@ -26,14 +35,18 @@ Class::Std::initialize();
my %GetSpecificCookieResult_of :ATTR(:get<GetSpecificCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetSpecificCookieResult
[ qw( GetSpecificCookieResult
) ],
{
GetSpecificCookieResult => \%GetSpecificCookieResult_of,
'GetSpecificCookieResult' => \%GetSpecificCookieResult_of,
},
{
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'GetSpecificCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
},
{
'GetSpecificCookieResult' => 'GetSpecificCookieResult',
}
);
@@ -44,11 +57,12 @@ __PACKAGE__->_factory(
} # end of BLOCK
1;
# __END__
=pod
@@ -61,6 +75,30 @@ MyElements::GetSpecificCookieResponse
Perl data type class for the XML Schema defined element
GetSpecificCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=item * GetSpecificCookieResult
$element->set_GetSpecificCookieResult($data);
$element->get_GetSpecificCookieResult();
=back
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::int;
use strict;
use warnings;
@@ -14,14 +15,12 @@ __PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::int
);
}
} # end of BLOCK
1;
# __END__
=pod
@@ -34,6 +33,12 @@ MyElements::int
Perl data type class for the XML Schema defined element
int from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::readNodeCount;
use strict;
use warnings;
@@ -17,13 +18,30 @@ use base qw(
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
# There's no variety - empty complexType
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
__PACKAGE__->_factory();
} # end of BLOCK
1;
# __END__
=pod
@@ -36,6 +54,21 @@ MyElements::readNodeCount
Perl data type class for the XML Schema defined element
readNodeCount from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=head1 METHODS
=head2 new

View File

@@ -1,3 +1,4 @@
package MyElements::readNodeCountResponse;
use strict;
use warnings;
@@ -16,6 +17,14 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
our $XML_ATTRIBUTE_CLASS;
undef $XML_ATTRIBUTE_CLASS;
sub __get_attr_class {
return $XML_ATTRIBUTE_CLASS;
}
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
@@ -26,14 +35,18 @@ Class::Std::initialize();
my %readNodeCountResult_of :ATTR(:get<readNodeCountResult>);
__PACKAGE__->_factory(
[ qw(
readNodeCountResult
[ qw( readNodeCountResult
) ],
{
readNodeCountResult => \%readNodeCountResult_of,
'readNodeCountResult' => \%readNodeCountResult_of,
},
{
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
'readNodeCountResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
},
{
'readNodeCountResult' => 'readNodeCountResult',
}
);
@@ -44,11 +57,12 @@ __PACKAGE__->_factory(
} # end of BLOCK
1;
# __END__
=pod
@@ -61,6 +75,30 @@ MyElements::readNodeCountResponse
Perl data type class for the XML Schema defined element
readNodeCountResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
=item * readNodeCountResult
$element->set_readNodeCountResult($data);
$element->get_readNodeCountResult();
=back
=head1 METHODS
=head2 new

View File

@@ -1,27 +1,26 @@
package MyElements::string;
use strict;
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('string');
__PACKAGE__->__set_nillable(true);
__PACKAGE__->__set_nillable(1);
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::string
);
}
} # end of BLOCK
1;
# __END__
=pod
@@ -32,7 +31,13 @@ MyElements::string
=head1 DESCRIPTION
Perl data type class for the XML Schema defined element
string from the namespace http://www.webserviceX.NET.
string from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 METHODS

View File

@@ -13,6 +13,8 @@ sub START {
$_[0]->set_proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx') if not $_[2]->{proxy};
$_[0]->set_class_resolver('MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie')
if not $_[2]->{class_resolver};
$_[0]->set_prefix($_[2]->{use_prefix}) if exists $_[2]->{use_prefix};
}
sub readNodeCount {
@@ -24,10 +26,11 @@ sub readNodeCount {
style => 'document',
body => {
'use' => 'literal',
namespace => '',
encodingStyle => '',
parts => [qw( MyElements::readNodeCount )],
'use' => 'literal',
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
encodingStyle => '',
parts => [qw( MyElements::readNodeCount )],
},
header => {
@@ -38,6 +41,7 @@ sub readNodeCount {
}, $body, $header);
}
sub GetFortuneCookie {
my ($self, $body, $header) = @_;
die "GetFortuneCookie must be called as object method (\$self is <$self>)" if not blessed($self);
@@ -47,10 +51,11 @@ sub GetFortuneCookie {
style => 'document',
body => {
'use' => 'literal',
namespace => '',
encodingStyle => '',
parts => [qw( MyElements::GetFortuneCookie )],
'use' => 'literal',
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
encodingStyle => '',
parts => [qw( MyElements::GetFortuneCookie )],
},
header => {
@@ -61,6 +66,7 @@ sub GetFortuneCookie {
}, $body, $header);
}
sub CountCookies {
my ($self, $body, $header) = @_;
die "CountCookies must be called as object method (\$self is <$self>)" if not blessed($self);
@@ -70,10 +76,11 @@ sub CountCookies {
style => 'document',
body => {
'use' => 'literal',
namespace => '',
encodingStyle => '',
parts => [qw( MyElements::CountCookies )],
'use' => 'literal',
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
encodingStyle => '',
parts => [qw( MyElements::CountCookies )],
},
header => {
@@ -84,6 +91,7 @@ sub CountCookies {
}, $body, $header);
}
sub GetSpecificCookie {
my ($self, $body, $header) = @_;
die "GetSpecificCookie must be called as object method (\$self is <$self>)" if not blessed($self);
@@ -93,10 +101,11 @@ sub GetSpecificCookie {
style => 'document',
body => {
'use' => 'literal',
namespace => '',
encodingStyle => '',
parts => [qw( MyElements::GetSpecificCookie )],
'use' => 'literal',
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
encodingStyle => '',
parts => [qw( MyElements::GetSpecificCookie )],
},
header => {
@@ -109,6 +118,7 @@ sub GetSpecificCookie {
1;
@@ -119,21 +129,20 @@ __END__
=head1 NAME
MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap - SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie Web Service
=head1 SYNOPSIS
use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap;
my $interface = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap->new();
my $response;
$response = $interface->readNodeCount();
$response = $interface->GetFortuneCookie();
$response = $interface->CountCookies();
$response = $interface->GetSpecificCookie();
=head1 DESCRIPTION
@@ -168,42 +177,58 @@ of the corresponding class can be passed instead of the marked hash ref.
You may pass any combination of objects, hash and list refs to these
methods, as long as you meet the structure.
List items (i.e. multiple occurences) are not displayed in the synopsis.
You may generally pass a list ref of hash refs (or objects) instead of a hash
ref - this may result in invalid XML if used improperly, though. Note that
SOAP::WSDL always expects list references at maximum depth position.
XML attributes are not displayed in this synopsis and cannot be set using
hash refs. See the respective class' documentation for additional information.
=head3 readNodeCount
Display the number of nodes specified in fortune XML document
$interface->readNodeCount(,,
Returns a L<MyElements::readNodeCountResponse|MyElements::readNodeCountResponse> object.
$response = $interface->readNodeCount(,,
);
=head3 GetFortuneCookie
Get a random fortune cookie from the XML document
$interface->GetFortuneCookie(,,
Returns a L<MyElements::GetFortuneCookieResponse|MyElements::GetFortuneCookieResponse> object.
$response = $interface->GetFortuneCookie(,,
);
=head3 CountCookies
Count the actual number of nodes in the XML document of fortunes
$interface->CountCookies(,,
Returns a L<MyElements::CountCookiesResponse|MyElements::CountCookiesResponse> object.
$response = $interface->CountCookies(,,
);
=head3 GetSpecificCookie
Get a specific cookie by the XML node number
$interface->GetSpecificCookie( {
Returns a L<MyElements::GetSpecificCookieResponse|MyElements::GetSpecificCookieResponse> object.
$response = $interface->GetSpecificCookie( {
index => $some_value, # int
},,
);
=head1 AUTHOR
Generated by SOAP::WSDL on Sun Dec 16 19:58:30 2007
Generated by SOAP::WSDL on Wed Dec 3 22:05:20 2008
=pod
=cut

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

@@ -1,3 +1,4 @@
package MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie;
use strict;
use warnings;
@@ -38,11 +39,13 @@ sub get_typemap {
__END__
__END__
=pod
=head1 NAME
MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie; - typemap for ::FullerData_x0020_Fortune_x0020_Cookie;
MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie - typemap for FullerData_x0020_Fortune_x0020_Cookie
=head1 DESCRIPTION

View File

@@ -1,6 +1,7 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use XML::Compile::SOAP11;
use XML::Compile::WSDL11;
use XML::Compile::Transport::SOAPHTTP;

View File

@@ -0,0 +1,29 @@
use lib '../../lib';
use lib '../lib';
use SOAP::WSDL::Server::Simple;
use base qw(HTTP::Server::Simple::CGI);
use MyServer::HelloWorld::HelloWorldSoap;
sub handle_request {
my ($self, $cgi) = @_;
my $server = MyServer::HelloWorld::HelloWorldSoap->new({
dispatch_to => 'main',
transport_class => 'SOAP::WSDL::Server::Simple',
});
$server->handle($cgi);
}
my $httpd = __PACKAGE__->new(8081);
$httpd->run();
sub sayHello {
my ($self, $body, $header) = @_;
my $name = $body->get_name();
my $givenName = $body->get_givenName();
return MyElements::sayHelloResponse->new({
sayHelloResult => "Hello $givenName $name"
})
}

View File

@@ -7,7 +7,8 @@
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/benchmark/">
targetNamespace="http://www.example.org/benchmark/"
elementFormDefault="qualified">
<xsd:element name="ListPerson">
<xsd:complexType>

440
example/wsdl/person.xml Normal file
View File

@@ -0,0 +1,440 @@
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<ListPersonResponse xmlns="http://www.example.org/benchmark/">
<out>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
<NewElement>
<PersonID>
<ID>1</ID>
</PersonID>
<Salutation>Salutation0</Salutation>
<Name>Name0</Name>
<GivenName>Martin</GivenName>
<DateOfBirth>1970-01-01</DateOfBirth>
<HomeAddress>
<Street>Street 0</Street>
<ZIP>00000</ZIP>
<City>City0</City>
<Country>Country0</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</HomeAddress>
<WorkAddress>
<Street>Somestreet 23</Street>
<ZIP>12345</ZIP>
<City>SomeCity</City>
<Country>Germany</Country>
<PhoneNumber>++499131123456</PhoneNumber>
<MobilePhoneNumber>++49150123456</MobilePhoneNumber>
</WorkAddress>
<Contracts>
<Contract>
<ContractID>100000</ContractID>
<ContractName>SomeContract0</ContractName>
</Contract>
<Contract>
<ContractID>100001</ContractID>
<ContractName>SomeContract1</ContractName>
</Contract>
<Contract>
<ContractID>100002</ContractID>
<ContractName>SomeContract2</ContractName>
</Contract>
<Contract>
<ContractID>100003</ContractID>
<ContractName>SomeContract3</ContractName>
</Contract>
</Contracts>
</NewElement>
</out>
</ListPersonResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

View File

@@ -10,15 +10,14 @@ use Carp;
use Scalar::Util qw(blessed);
use SOAP::WSDL::Client;
use SOAP::WSDL::Expat::WSDLParser;
use Class::Std::Fast;
use Class::Std::Fast constructor => 'none';
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use LWP::UserAgent;
our $VERSION= '2.00_25';
use version; our $VERSION = qv('3.002');
my %no_dispatch_of :ATTR(:name<no_dispatch>);
my %wsdl_of :ATTR(:name<wsdl>);
my %proxy_of :ATTR(:name<proxy>);
my %autotype_of :ATTR(:name<autotype>);
my %outputxml_of :ATTR(:name<outputxml> :default<0>);
my %outputtree_of :ATTR(:name<outputtree>);
@@ -42,7 +41,6 @@ my %LOOKUP = (
no_dispatch => \%no_dispatch_of,
class_resolver => \%class_resolver_of,
wsdl => \%wsdl_of,
proxy => \%proxy_of,
autotype => \%autotype_of,
outputxml => \%outputxml_of,
outputtree => \%outputtree_of,
@@ -94,12 +92,30 @@ for my $method (keys %LOOKUP ) {
}
my $ident = ident $self;
$self->wsdlinit() if ($wsdl_of{ $ident });
$client_of{ $ident } = SOAP::WSDL::Client->new();
$self->wsdlinit() if ($wsdl_of{ $ident });
return $self;
}
}
sub set_proxy {
my $self = shift;
return $self->get_client()->set_proxy(@_);
}
sub get_proxy {
my $self = shift;
return $self->get_client()->get_proxy();
}
sub proxy {
my $self = shift;
if (@_) {
return $self->set_proxy(@_);
}
return $self->get_proxy();
}
sub wsdlinit {
my ($self, %opt) = @_;
my $ident = ident $self;
@@ -109,6 +125,7 @@ sub wsdlinit {
? (keep_alive => 1)
: ()
);
$lwp->agent(qq[SOAP::WSDL $VERSION]);
my $response = $lwp->get( $wsdl_of{ $ident } );
croak $response->message() if ($response->code != 200);
@@ -132,6 +149,15 @@ sub wsdlinit {
$servicename_of{ $ident } = $opt{servicename} if $opt{servicename};
$portname_of{ $ident } = $opt{portname} if $opt{portname};
$self->_wsdl_init_methods();
# pass-through keep_alive if we need it...
$self->get_client()->set_proxy(
$port_of{ $ident }->first_address()->get_location(),
$keep_alive_of{ $ident } ? (keep_alive => 1) : (),
);
return $self;
} ## end sub wsdlinit
@@ -139,8 +165,8 @@ sub _wsdl_get_service :PRIVATE {
my $ident = ident shift;
my $wsdl = $definitions_of{ $ident };
return $service_of{ $ident } = $servicename_of{ $ident }
? $wsdl->find_service( $wsdl->get_targetNamespace() , $servicename_of{ $ident } )
: $service_of{ $ident } = $wsdl->get_service()->[ 0 ];
? $wsdl->find_service( $wsdl->get_targetNamespace() , $servicename_of{ $ident } )
: ( $service_of{ $ident } = $wsdl->get_service()->[ 0 ] );
} ## end sub _wsdl_get_service
sub _wsdl_get_port :PRIVATE {
@@ -148,9 +174,10 @@ sub _wsdl_get_port :PRIVATE {
my $wsdl = $definitions_of{ $ident };
my $ns = $wsdl->get_targetNamespace();
return $port_of{ $ident } = $portname_of{ $ident }
? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } )
: $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ];
? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } )->[ 0 ]
: ( $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ] );
}
sub _wsdl_get_binding :PRIVATE {
my $self = shift;
my $ident = ident $self;
@@ -160,6 +187,7 @@ sub _wsdl_get_binding :PRIVATE {
or croak "no binding found for ", $port->get_binding();
return $binding_of{ $ident };
}
sub _wsdl_get_portType :PRIVATE {
my $self = shift;
my $ident = ident $self;
@@ -169,6 +197,7 @@ sub _wsdl_get_portType :PRIVATE {
or croak "cannot find portType for " . $binding->get_type();
return $porttype_of{ $ident };
}
sub _wsdl_init_methods :PRIVATE {
my $self = shift;
my $ident = ident $self;
@@ -176,7 +205,7 @@ sub _wsdl_init_methods :PRIVATE {
my $ns = $wsdl->get_targetNamespace();
# get bindings, portType, message, part(s) - use private methods for clear separation...
$self->_wsdl_get_service if not ($service_of{ $ident });
$self->_wsdl_get_service();
$self->_wsdl_get_portType();
$method_info_of{ $ident } = {};
@@ -187,9 +216,10 @@ sub _wsdl_init_methods :PRIVATE {
# get SOAP Action
# SOAP-Action is a required HTTP Header, so we need to look it up...
# There must be a soapAction uri - or the WSDL is invalid (and
# it's not us to prove that...)
my $soap_binding_operation = $binding_operation->get_operation()->[0];
$method->{ soap_action } = $soap_binding_operation ?
$soap_binding_operation->get_soapAction() : $method;
$method->{ soap_action } = $soap_binding_operation->get_soapAction();
# get parts
# 1. get operation from port
@@ -204,7 +234,10 @@ sub _wsdl_init_methods :PRIVATE {
my $message = $wsdl->find_message( $ns, $localname )
or croak "Message {$ns}$localname not found in WSDL definition";
if (my $body=$binding_operation->first_input()->first_body()) {
# Is body not required? So there must be one? Do we need the "if"?
# if (
my $body=$binding_operation->first_input()->first_body();
# {
if ($body->get_parts()) {
$method->{ parts } = []; # make sure it's empty
my $message_part_ref = $message->get_part();
@@ -216,7 +249,9 @@ sub _wsdl_init_methods :PRIVATE {
grep { $_->get_name() eq $name } @{ $message_part_ref };
}
}
}
# }
# A body does not need to specify the parts of a messages.
# Use all of the message's parts if it does not.
$method->{ parts } ||= $message->get_part();
# rpc / encoded methods may have a namespace specified.
@@ -234,6 +269,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 };
@@ -249,12 +288,6 @@ sub call {
my $client = $client_of{ $ident };
# pass-through keep_alive if we need it...
$client->set_proxy( $proxy_of{ $ident }
|| $port_of{ $ident }->first_address()->get_location(),
$keep_alive_of{ $ident } ? (keep_alive => 1) : (),
);
$client->set_no_dispatch( $no_dispatch_of{ $ident } );
$client->set_outputxml( $outputxml_of{ $ident } ? 1 : 0 );
@@ -267,7 +300,7 @@ sub call {
&& ( ! $no_dispatch_of{ $ident } ) ) {
require SOAP::WSDL::Deserializer::SOM;
$client->set_deserializer( SOAP::WSDL::Deserializer::SOM->new() );
};
}
my $method_info = $method_info_of{ $ident }->{ $method };
@@ -316,7 +349,24 @@ __END__
SOAP::WSDL - SOAP with WSDL support
=head1 Overview
=head1 NOTICE
This module is B<not> recommended for new application development.
Please use L<XML::Compile::SOAP> or L<SOAP::Lite> instead if possible.
This module has a large number of known bugs and is not being actively developed.
This 3.0 release is intended to update the module to pass tests on newer Perls.
This is a service to existing applications already dependent on this module.
=head1 SYNOPSIS
my $soap = SOAP::WSDL->new(
wsdl => 'file://bla.wsdl',
);
my $result = $soap->call('MyMethod', %data);
=head1 DESCRIPTION
For creating Perl classes instrumenting a web service with a WSDL definition,
read L<SOAP::WSDL::Manual>.
@@ -324,15 +374,16 @@ read L<SOAP::WSDL::Manual>.
For using an interpreting (thus slow and somewhat troublesome) WSDL based
SOAP client, which mimics L<SOAP::Lite|SOAP::Lite>'s API, read on.
=head1 SYNOPSIS
Creating Interface classes is the recommended usage.
my $soap = SOAP::WSDL->new(
wsdl => 'file://bla.wsdl',
);
my $result = $soap->call('MyMethod', %data);
Did I say you should create interface classes following the steps in
L<SOAP::WSDL::Manual>?
=head1 DESCRIPTION
If you're migrating from earlier versions of SOAP::WSDL, you should read the
MIGRATING documentation.
The stuff below is for users of the 1.2x SOAP::WSDL series. All others,
please refer to L<SOAP::WSDL::Manual>
SOAP::WSDL provides easy access to Web Services with WSDL descriptions.
@@ -436,7 +487,7 @@ Class resolver
'Person/Name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Person/FirstName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
);
sub get_class { return $typemap{ $_[1] } };
1;
@@ -495,7 +546,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
@@ -516,6 +567,34 @@ You may pass the servicename and portname as attributes to wsdlinit, though.
=back
=head1 Differences to previous versions
The following functionality is no longer supported:
=head2 Operation overloading
The SOAP standard allows operation overloading - that is, you may specify
SOAP operations with more than one message. The client/server than can
choose which message to send. This SOAP feature is usually used similar
to the use of methods with different argument lists in C++.
Operation overloading is no longer supported. The WS-I Basic profile does
not operation overloading. The same functionality as operation overloading
can be obtained by using a choice declaration in the XML Schema.
=head2 readable
Readable has no effect any more. If you need readable debug output, copy the
SOAP message to your favorite XML editor and run the source format command.
Outputting readable XML requires lots of programming for little use: The
resulting XMl is still quite unreadable.
=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
@@ -556,7 +635,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
@@ -596,8 +675,35 @@ details.
=head1 BUGS AND LIMITATIONS
The bug tracker is at L<< https://rt.cpan.org/Dist/Display.html?Queue=SOAP-WSDL >>.
This module is in legacy maintenance mode.
Only show stopper bugs are being fixed, until/unless someone wishes to resume active development on it.
Scott Walters, C<scott@slowass.net> has obtained co-mainter from the CPAN admins for the purpose of applying existing fixes people have submit to
the RT tracker, and to apply other fixes as needed to get the module to install and run on newer Perls.
Non show-stopper bugs reports without fixes will be added to this list of limitations.
Of course, fixes for these and other bugs are welcome.
Scott does not get email from L<< rt.cpan.org >>, so please drop an email to him at C<< scott@slowass.net >> if you open a ticket there.
=over
=item * Breaks the idiom C<< $package->can("SUPER::method") >> in your code
If you redefine C<< UNIVERSAL::can() >>, and someone tries to do C<< $package->can("SUPER::method") >>, it'll look at your packages C<@ISA>, not theirs.
This module does precicely that, by way of its dependency on C<Class::Std::Fast>.
=item * $obj == undef does not work in perl 5.8.6 and perl 5.8.7
Due to some strange behaviour in perl 5.8.6 and perl 5.8.7, stringification
overloading is not triggered during comparison with undef.
While this is probably harmless in most cases, it's important to know that
you need to do
defined( $obj->get_value() )
to check for undef values in simpleType objects.
=item * perl 5.8.0 or higher required
SOAP::WSDL needs perl 5.8.0 or higher. This is due to a bug in perls
@@ -605,30 +711,30 @@ before - see http://aspn.activestate.com/ASPN/Mail/Message/perl5-porters/929746
=item * Apache SOAP datatypes are not supported
You currently can't use SOAP::WSDL with Apache SOAP datatypes like map.
If you want this changed, email me a copy of the specs, please.
You can't use SOAP::WSDL with Apache SOAP datatypes like map.
=item * Incomplete XML Schema definitions support
XML Schema attribute definitions are not supported yet.
This section describes the limitations of SOAP::WSDL, that is the interpreting
SOAP client. For limitations of L<wsdl2perl.pl|wsdl2perl.pl> generated
SOAP clients, see L<SOAP::WSDL::Manual::XSD>.
Importing external definitions is not supported yet.
XML Schema attribute definitions are not supported in interpreting mode.
The following XML Schema definitions varieties are not supported:
The following XML Schema definitions varieties are not supported in
interpreting mod:
group
union
simpleContent
The following XML Schema definition content model is only partially
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.
@@ -638,17 +744,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
@@ -672,10 +778,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.
@@ -698,6 +804,12 @@ L<http://www.cpanforum.com/dist/SOAP-WSDL>
=head1 ACKNOWLEDGMENTS
Scott Walters wrote:
This code incorporates fixes contributed by C<< NORDIC@cpan.org >>, C<< dam@cpan.org >>, C<< sven.schober@uni-ulm.de >>, myself, and others.
Martin Kutter wrote:
There are many people out there who fostered SOAP::WSDL's developement.
I would like to thank them all (and apologize to all those I have forgotten).
@@ -706,34 +818,47 @@ became v1.23)
David Bussenschutt, Damian A. Martinez Gelabert, Dennis S. Hennen, Dan Horne,
Peter Orvos, Mark Overmeer, Jon Robens, Isidro Vila Verde and Glenn Wood
spotted bugs and/or suggested improvements in the 1.2x releases.
(in alphabetical order) spotted bugs and/or suggested improvements in
the 1.2x releases.
JT Justman and Noah Robin provided early feedback and bug reports for
the 2.xx pre-releases.
Adam Kennedy checked and suggested improvements on metadata and dependencies
in the 2.xx pre-releases.
Andreas 'ac0v' Specht constantly asked for better performance.
JT Justman provided early feedback for the 2.xx pre-releases.
Matt S. Trout encouraged me "to get a non-dev-release out."
Numerous people sent me their real-world WSDL files for testing. Thank you.
CPAN Testers provided most valuable (automated) feedback. Thanks a lot.
Numerous people sent me their real-world WSDL files and error reports for
testing. Thank you.
Noah Robin contributed lots of documentation fixes, and the mod_perl server,
and eventually joined SOAP::WSDL's developement. Thanks.
Mark Overmeer wrote XML::Compile::SOAP - competition is good for business.
Paul Kulchenko and Byrne Reese wrote and maintained SOAP::Lite and
thus provided a base (and counterpart) for SOAP::WSDL.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
Copyright 2004-2008 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
Scott Walters E<lt>scott@slowass.net<gt> 2014
Martin Kutter E<lt>martin.kutter fen-net.deE<gt> 2004-2008
=head1 REPOSITORY INFORMATION
$Rev: 477 $
$LastChangedBy: kutterma $
$Id: WSDL.pm 477 2007-12-24 10:23:52Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
https://github.com/scrottie/SOAP-WSDL
=cut

View File

@@ -1,43 +1,64 @@
package SOAP::WSDL::Base;
use strict;
use warnings;
use strict; use warnings;
use Class::Std::Fast::Storable;
use List::Util qw(first);
use List::Util;
use Scalar::Util;
use Carp qw(croak carp confess);
our $VERSION='2.00_27';
our $VERSION = $SOAP::WSDL::VERSION;
my %id_of :ATTR(:name<id> :default<()>);
my %name_of :ATTR(:name<name> :default<()>);
my %documentation_of :ATTR(:name<documentation> :default<()>);
my %targetNamespace_of :ATTR(:name<targetNamespace> :default<()>);
my %xmlns_of :ATTR(:name<xmlns> :default<{}>);
my %parent_of :ATTR(:name<parent> :default<()>);
my %id_of :ATTR(:name<id> :default<()>);
my %lang_of :ATTR(:name<lang> :default<()>);
my %name_of :ATTR(:name<name> :default<()>);
my %namespace_of :ATTR(:name<namespace> :default<()>);
my %documentation_of :ATTR(:name<documentation> :default<()>);
my %annotation_of :ATTR(:name<annotation> :default<()>);
my %targetNamespace_of :ATTR(:name<targetNamespace> :default<"">);
my %xmlns_of :ATTR(:name<xmlns> :default<{}>);
my %parent_of :ATTR(:get<parent> :default<()>);
my %namespaces_of :ATTR(:default<{}>);
sub namespaces {
return shift->get_xmlns();
}
sub BUILD {
my ($self, $ident, $arg_ref) = @_;
if (defined $arg_ref->{ parent }) {
$parent_of{ $ident } = delete $arg_ref->{ parent },
Scalar::Util::weaken($parent_of{ $ident });
}
}
sub START {
my ($self, $ident, $arg_ref) = @_;
$xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' };
$xmlns_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace';
$namespaces_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' };
$namespaces_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace';
}
sub DEMOLISH {
my $self = shift;
# delete upward references
delete $parent_of{ ident $self };
return;
#
# set_parent is hand-implemented to break up (weaken) the circular reference
# between an object and it's parent
#
sub set_parent {
$parent_of{ ${ $_[0]} } = $_[1];
Scalar::Util::weaken($parent_of{ ${ $_[0]} });
}
sub STORABLE_freeze_pre :CUMULATIVE {};
sub STORABLE_freeze_post :CUMULATIVE {};
sub STORABLE_thaw_pre :CUMULATIVE {};
sub STORABLE_thaw_post :CUMULATIVE { return $_[0] };
# _accept is here to be called by visitor.
# The visitor pattern is a level of indirection - here the visitor calls
# $object->_accept($visitor) on each object, which in turn calls
# $visitor->visit_$class( $object ) where $class is the object's class.
#
sub _accept {
my $self = shift;
my $class = ref $self;
$class =~ s{ \A SOAP::WSDL:: }{}xms;
$class =~ s{ (:? :: ) }{_}gxms;
my $method = "visit_$class";
no strict qw(refs); ## no critic ProhibitNoStrict
no strict qw(refs);
return shift->$method( $self );
}
@@ -52,13 +73,12 @@ sub AUTOMETHOD {
if ($subname =~s{^push_}{}xms) {
my $getter = "get_$subname";
my $setter = "set_$subname";
## Checking here is paranoid - will fail fatally if
## there is no setter...
## And we would have to check getters, too.
## Maybe do it the Conway way via the Symbol table...
## ... can is way slow...
# Checking here is paranoid - will fail fatally if there is no setter.
# And we would have to check getters, too.
# Maybe do it the Conway way via the Symbol table...
# ... can is way slow...
return sub {
no strict qw(refs); ## no critic ProhibitNoStrict
no strict qw(refs);
my $old_value = $self->$getter();
# Listify if not a list ref
$old_value = $old_value ? [ $old_value ] : [] if not ref $old_value;
@@ -72,7 +92,7 @@ sub AUTOMETHOD {
elsif ($subname =~s {^find_}{get_}xms) {
@values = @{ $values[0] } if ref $values[0] eq 'ARRAY';
return sub {
return first {
return List::Util::first {
$_->get_targetNamespace() eq $values[0] &&
$_->get_name() eq $values[1]
}
@@ -87,20 +107,30 @@ sub AUTOMETHOD {
return $result_ref->[0];
};
}
confess "$subname not found in class " . ref $self;
return;
}
sub init {
my ($self, @args) = @_;
foreach my $value (@args)
{
foreach my $value (@args) {
croak @args if (not defined ($value->{ Name }));
if ($value->{ Name } =~m{^xmlns\:}xms) {
# add namespaces
$xmlns_of{ ident $self }->{ $value->{ LocalName } } = $value->{ Value };
next;
}
# check for namespae-qualified attributes.
# neither XML Schema, nor WSDL1.1, nor the SOAP binding allow
# namespace-qualified attribute names
my ($ns, $localname) = split /\|/, $value->{ Name };
if ($ns) {
warn "found unrecognised attribute \{$ns}$localname (ignored)";
next;
}
my $name = $value->{ LocalName };
my $method = "set_$name";
$self->$method( $value->{ Value } );
@@ -109,28 +139,41 @@ sub init {
}
sub expand {
my ($self, , $qname) = @_;
my $ns_of = $self->get_xmlns();
my ($self, $qname) = @_;
my $ns_of = $self->namespaces();
my $parent;
if (not $qname=~m{:}xm) {
if (defined $ns_of->{ '#default' }) {
# TODO check. Returning the targetNamespace for the default ns
# is probably wrong
#return $self->get_targetNamespace(), $qname;
return $ns_of->{ '#default' }, $qname;
}
if ($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()) {
if ($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;
*_expand = \&expand;
sub schema {
my $parent = $_[0]->get_parent();
return if ! defined $parent;
return $parent if $parent->isa('SOAP::WSDL::XSD::Schema');
return $parent->schema();
}
1;
__END__

View File

@@ -2,9 +2,11 @@ package SOAP::WSDL::Binding;
use strict;
use warnings;
use Class::Std::Fast::Storable;
use List::Util qw(first);
use base qw(SOAP::WSDL::Base);
our $VERSION = $SOAP::WSDL::VERSION;
my %operation_of :ATTR(:name<operation> :default<()>);
my %type_of :ATTR(:name<type> :default<()>);
my %transport_of :ATTR(:name<transport> :default<()>);

View File

@@ -11,20 +11,23 @@ use SOAP::WSDL::Factory::Serializer;
use SOAP::WSDL::Factory::Transport;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION = '2.00_27';
our $VERSION = $SOAP::WSDL::VERSION;
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<()>);
my %soap_version_of :ATTR(:get<soap_version> :init_attr<soap_version> :default<'1.1'>);
my %soap_version_of :ATTR(:get<soap_version> :init_attr<soap_version> :default<1.1>);
my %on_action_of :ATTR(:name<on_action> :default<()>);
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>); #/#trick editors
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf-8>); #/#trick editors
my %encoding_of :ATTR(:name<encoding> :default<utf-8>);
my %serializer_of :ATTR(:name<serializer> :default<()>);
my %deserializer_of :ATTR(:name<deserializer> :default<()>);
my %deserializer_args_of :ATTR(:name<deserializer_args> :default<{}>);
sub BUILD {
my ($self, $ident, $attrs_of_ref) = @_;
@@ -61,7 +64,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 +74,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 +97,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 +127,7 @@ sub call {
method => $operation,
body => $data,
header => $header,
options => {prefix => $prefix_of{ $ident }},
});
return $envelope if $self->no_dispatch();
@@ -145,6 +149,7 @@ sub call {
my $response = $transport->send_receive(
endpoint => $self->get_endpoint(),
content_type => $content_type_of{ $ident },
encoding => $encoding_of{ $ident },
envelope => $envelope,
action => $soap_action,
# on_receive_chunk => sub {} # optional, may be used for parsing large responses as they arrive.
@@ -153,8 +158,10 @@ sub call {
return $response if ($outputxml_of{ $ident } );
# get deserializer
use Data::Dumper;
$deserializer_of{ $ident } ||= SOAP::WSDL::Factory::Deserializer->get_deserializer({
soap_version => $soap_version_of{ $ident },
%{ $deserializer_args_of{ $ident } },
});
# set class resolver if serializer supports it
@@ -164,20 +171,29 @@ sub call {
# Try deserializing response - there may be some,
# even if transport did not succeed (got a 500 response)
if ( $response ) {
my ($result_body, $result_header) = eval {
$deserializer_of{ $ident }->deserialize( $response );
# as our faults are false, returning a success marker is the only
# reliable way of determining whether the deserializer succeeded.
# Custom deserializers may return an empty list, or undef,
# and $@ is not guaranteed to be undefined.
my ($success, $result_body, $result_header) = eval {
(1, $deserializer_of{ $ident }->deserialize( $response ));
};
if (not $@) {
if (defined $success) {
return wantarray
? ($result_body, $result_header)
: $result_body;
}
return $deserializer_of{ $ident }->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$response"
});
elsif (blessed $@) { #}&& $@->isa('SOAP::WSDL::SOAP::Typelib::Fault11')) {
return $@;
}
else {
return $deserializer_of{ $ident }->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$response"
});
}
};
# if we had no success (Transport layer error status code)
@@ -259,19 +275,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 +332,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 +352,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 +370,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,10 +409,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 455 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Client.pm 455 2007-12-14 15:50:16Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
$Id: Client.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
=cut

View File

@@ -4,68 +4,45 @@ use warnings;
use base 'SOAP::WSDL::Client';
use Scalar::Util qw(blessed);
our $VERSION = '2.00_25';
our $VERSION = $SOAP::WSDL::VERSION;
sub call {
my ($self, $method, $body, $header) = @_;
# Treat non-objects special
if (not blessed $body) {
# make sure there's something sensible in our body data
$body = {} if not defined $body;
$body = ref $body eq 'ARRAY' ? $body : [ $body ];
my $index = 0;
my @part_from;
foreach my $part (@{ $body }) {
my $class = $method->{ body }->{ parts }->[$index];
eval "require $class" || die $@;
push @part_from, $class->new($part);
$index++;
my @body_from = @{ $body }; # make a copy
# build list of parts as objects initialized with
# parameters given
my @part_from = ();
foreach my $class (@{ $method->{ body }->{ parts } }) {
eval "require $class" || die $@; ## no critic (ProhibitStringyEval)
push @part_from, $class->new(shift(@body_from) || {});
}
# it's either the first part or a list ref with all parts...
$body = $#part_from ? \@part_from : $part_from[0];
}
# if we have a header
if (%{ $method->{ header } }) {
# treat non object special - as above, but only for one
if (not blessed $header) {
my $class = $method->{ header }->{ parts }->[0];
eval "require $class" || die $@;
eval "require $class" || die $@; ## no critic (ProhibitStringyEval)
$header = $class->new($header);
}
}
return $self->SUPER::call($method, $body, $header);
}
#sub __create_methods {
# my ($package, %info_of) = @_;
#
# no strict qw(refs);
# no warnings qw(redefine);
# for my $method (keys %info_of){
# my ($soap_action, @parts);
#
# # up to 2.00_10 we had list refs...
# if (ref $info_of{ $method }eq 'HASH') {
# @parts = @{ $info_of{ $method }->{ parts } };
# $soap_action = $info_of{ $method }->{ soap_action };
# }
# else {
# die "Pre-v2.00_10 Interfaces are no longer supported. Please re-generate your interface.";
# }
#
# *{ "$package\::$method" } = sub {
# my $self = shift;
# my @param = map {
# my $data = shift || {};
# eval "require $_";
# $_->new( $data );
# } @parts;
#
# return $self->SUPER::call( {
# operation => $method,
# soap_action => $soap_action,
# }, @param );
# }
# }
#}
1;
__END__
@@ -88,6 +65,13 @@ SOAP::WSDL::Client::Base - Factory class for WSDL-based SOAP access
Factory class for creating interface classes. Should probably be renamed to
SOAP::WSDL::Factory::Interface...
=head1 METHODS
=head2 call
Abstraction layer method between the generated interfaces and
L<SOAP::WSDL::Client|SOAP::WSDL::Client>.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
@@ -101,9 +85,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 440 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Base.pm 440 2007-12-04 22:24:33Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $
$Id: Base.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $
=cut

View File

@@ -1,30 +1,26 @@
package SOAP::WSDL::Definitions;
use utf8;
use strict;
use warnings;
use Carp;
use File::Basename;
use File::Path;
use List::Util qw(first);
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
our $VERSION='2.00_27';
our $VERSION = $SOAP::WSDL::VERSION;
my %types_of :ATTR(:name<types> :default<[]>);
my %message_of :ATTR(:name<message> :default<()>);
my %portType_of :ATTR(:name<portType> :default<()>);
my %binding_of :ATTR(:name<binding> :default<()>);
my %service_of :ATTR(:name<service> :default<()>);
my %namespace_of :ATTR(:name<namespace> :default<()>);
my %types_of :ATTR(:name<types> :default<[]>);
my %message_of :ATTR(:name<message> :default<[]>);
my %portType_of :ATTR(:name<portType> :default<[]>);
my %binding_of :ATTR(:name<binding> :default<[]>);
my %service_of :ATTR(:name<service> :default<[]>);
my %namespace_of :ATTR(:name<namespace> :default<()>);
# must be attr for Class::Std::Fast::Storable
my %attributes_of :ATTR();
%attributes_of = (
binding => \%binding_of,
message => \%message_of,
portType => \%portType_of,
service => \%service_of,
#my %attributes_of :ATTR();
my %attributes_of = (
binding => \%binding_of,
message => \%message_of,
portType => \%portType_of,
service => \%service_of,
);
# Function factory - we could be writing this method for all %attribute
@@ -44,6 +40,7 @@ BLOCK: {
}
}
1;
=pod
@@ -72,7 +69,7 @@ Returns the service matching the namespace/localname pair passed as arguments.
Accessors/Mutators for accessing / setting the E<gt>bindingE<lt> child
element(s).
=head2 find_service
=head2 find_binding
Returns the binding matching the namespace/localname pair passed as arguments.
@@ -94,7 +91,7 @@ Returns the portType matching the namespace/localname pair passed as arguments.
Accessors/Mutators for accessing / setting the E<gt>messageE<lt> child
element(s).
=head2 find_service
=head2 find_message
Returns the message matching the namespace/localname pair passed as arguments.
@@ -118,10 +115,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 477 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Definitions.pm 477 2007-12-24 10:23:52Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Definitions.pm $
$Id: Definitions.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://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';
our $VERSION = $SOAP::WSDL::VERSION;
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
@@ -38,7 +38,7 @@ sub deserialize {
sub generate_fault {
my ($self, $args_from_ref) = @_;
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => $args_from_ref->{ code } || 'soap:Client',
faultcode => $args_from_ref->{ code } || 'SOAP-ENV:Client',
faultactor => $args_from_ref->{ role } || 'urn:localhost',
faultstring => $args_from_ref->{ message } || "Unknown error"
});
@@ -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.
@@ -139,9 +139,20 @@ a parse error appears
=back
=head1 METHODS
=head2 deserialize
Deserializes the message.
=head2 generate_fault
Generates a L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
object and returns it.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
Copyright 2004-2008 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself.
@@ -152,9 +163,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 427 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Hash.pm 427 2007-12-02 22:20:24Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/Hash.pm $
$Id: Hash.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://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';
our $VERSION = $SOAP::WSDL::VERSION;
our @ISA;
eval {
@@ -13,6 +13,18 @@ or die "Cannot load SOAP::Lite.
Cannot deserialize to SOM object without SOAP::Lite.
Please install SOAP::Lite.";
sub deserialize {
my $self = shift;
my $result = eval { $self->SUPER::deserialize(@_) };
if ($@) {
return SOAP::Fault->new(
faultactor => 'SOAP-ENV:Server',
faultstring => $@,
);
}
return $result;
}
sub generate_fault {
my ($self, $args_from_ref) = @_;
# code, message, detail, actor
@@ -37,7 +49,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.
@@ -66,13 +78,24 @@ This may be XML including mixed content, attachements and other XML data not
SOAP::WSDL::Deserializer::SOM is a subclass of L<SOAP::Deserializer|SOAP::Deserializer>
from the L<SOAP::Lite|SOAP::Lite> package.
=head1 METHODS
=head2 deserialize
Deserializes a XML sting into a SOAP::SOM object. Returns a SOAP::Fault object
on deserialization errors.
=head2 generate_fault
Dies with a SOAP::Fault object.
=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__ );
@@ -85,8 +108,8 @@ SOAP version just use the following lines:
=item * No on_fault handler
You cannot specify what to do when an error occurs - SOAP::WSDL will die
with a SOAP::Fault object on transport errors.
You cannot specify what to do when an error occurs - SOAP::WSDL will return
a SOAP::Fault object on transport errors.
=back
@@ -99,6 +122,9 @@ with a SOAP::Fault object on transport errors.
SOAP::WSDL::Deserializer::SOM will die with a SOAP::Fault object on calls
to generate_fault.
This also means that a SOAP::Fault may be thrown as exception when using
=back
=head1 LICENSE AND COPYRIGHT
@@ -114,9 +140,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 391 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: SOM.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $
$Id: SOM.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $
=cut

View File

@@ -5,30 +5,41 @@ use Class::Std::Fast::Storable;
use SOAP::WSDL::SOAP::Typelib::Fault11;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION='2.00_25';
our $VERSION = $SOAP::WSDL::VERSION;
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
my %strict_of :ATTR(:get<strict> :init_arg<strict> :default<1>);
my %parser_of :ATTR();
my %parser_of :ATTR();
sub set_strict {
undef $parser_of{${$_[0]}};
$strict_of{${$_[0]}} = $_[1];
}
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
# ignore all options except 'class_resolver'
for (keys %{ $args_of_ref }) {
delete $args_of_ref->{ $_ } if $_ ne 'class_resolver';
next if $_ eq 'strict';
next if $_ eq 'class_resolver';
delete $args_of_ref->{ $_ };
}
}
sub deserialize {
my ($self, $content) = @_;
$parser_of{ ${ $self } } ||= SOAP::WSDL::Expat::MessageParser->new();
$parser_of{ ${ $self } }->class_resolver( $class_resolver_of{ ident $self } );
$parser_of{ ${ $self } } = SOAP::WSDL::Expat::MessageParser->new({
strict => $strict_of{ ${ $self } }
})
if not $parser_of{ ${ $self } };
$parser_of{ ${ $self } }->class_resolver( $class_resolver_of{ ${ $self } } );
$content =~ s{^<\?xml version="1.0" *\?>}{}; # XML::Parser::Expat apparently doesn't like this.
eval { $parser_of{ ${ $self } }->parse_string( $content ) };
if ($@) {
return $self->generate_fault({
code => 'soap:Server',
code => 'SOAP-ENV:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$content"
@@ -40,7 +51,7 @@ sub deserialize {
sub generate_fault {
my ($self, $args_from_ref) = @_;
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => $args_from_ref->{ code } || 'soap:Client',
faultcode => $args_from_ref->{ code } || 'SOAP-ENV:Client',
faultactor => $args_from_ref->{ role } || 'urn:localhost',
faultstring => $args_from_ref->{ message } || "Unknown error"
});
@@ -71,9 +82,23 @@ 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 OPTIONS
=over
=item * strict
Enables/disables strict XML processing. Strict processing is enabled by
default. To disable strict XML processing pass the following to the
constructor or use the C<set_strict> method:
strict => 0
=back
=head1 METHODS
=head2 deserialize
@@ -85,6 +110,10 @@ Deserializes the message.
Generates a L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
object and returns it.
=head2 set_strict
Enable/disable strict XML parsing. Default is enabled.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
@@ -98,9 +127,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 427 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: XSD.pm 427 2007-12-02 22:20:24Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $
$Id: XSD.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $
=cut

View File

@@ -1,23 +1,86 @@
package SOAP::WSDL::Expat::Base;
use strict;
use warnings;
use URI;
use XML::Parser::Expat;
our $VERSION = '2.00_27';
# TODO: convert to Class::Std::Fast based class - hash based classes suck.
our $VERSION = $SOAP::WSDL::VERSION;
sub new {
my ($class, $args) = @_;
my $self = {};
my ($class, $arg_ref) = @_;
my $self = {
data => undef,
};
bless $self, $class;
$self->set_user_agent($arg_ref->{ user_agent })
if $arg_ref->{ user_agent };
$self->{ parsed } = $arg_ref->{ parsed } if $arg_ref->{ parsed };
return $self;
}
sub clone {
my $self = shift;
my $class = ref $self;
my $clone = $class->new($self);
return $clone;
}
sub set_uri { $_[0]->{ uri } = $_[1]; }
sub get_uri { return $_[0]->{ uri }; }
sub set_user_agent { $_[0]->{ user_agent } = $_[1]; }
sub get_user_agent { return $_[0]->{ user_agent }; }
# Mark a URI as "already parsed"
sub set_parsed {
my ($self, $uri) = @_;
$self->{ parsed }->{ $uri } = 1;
return;
}
# returns true if a specific URI has already been parsed
sub is_parsed {
my ($self, $uri) = @_;
return exists $self->{ parsed }->{ $uri };
}
# parse a URI. This is the preferred parsing method for WSDL files, as it's
# the only one allowing automatic import resolution
sub parse_uri {
my $self = shift;
my $uri = shift;
if ($self->is_parsed($uri)){
warn "$uri already imported; ignoring it.\n";
return;
}
$self->set_parsed($uri);
$self->set_uri( $uri );
if (not $self->{ user_agent }) {
require LWP::UserAgent;
$self->{ user_agent } = LWP::UserAgent->new();
}
my $response = $self->{ user_agent }->get($uri);
die $response->message() if $response->code() ne '200';
return $self->parse( $response->content() );
}
sub parse {
eval {
$_[0]->_initialize( XML::Parser::Expat->new( Namespaces => 1 ) )->parse( $_[1] );
$_[0]->{ parser }->release();
};
$_[0]->{ parser }->xpcroak( $@ ) if $@;
delete $_[0]->{ parser };
return $_[0]->{ data };
}
@@ -27,6 +90,7 @@ sub parsefile {
$_[0]->{ parser }->release();
};
$_[0]->{ parser }->xpcroak( $@ ) if $@;
delete $_[0]->{ parser };
return $_[0]->{ data };
}

View File

@@ -4,7 +4,7 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Expat::Base);
our $VERSION = '2.00_27';
our $VERSION = $SOAP::WSDL::VERSION;
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

@@ -1,19 +1,20 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::MessageParser;
use strict;
use warnings;
use Carp qw(croak confess);
our $VERSION = q{2.00_27};
use strict; use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use base qw(SOAP::WSDL::Expat::Base);
require Class::Std::Fast;
BEGIN { require Class::Std::Fast };
our $VERSION = $SOAP::WSDL::VERSION;
# GLOBALS
my $OBJECT_CACHE_REF = Class::Std::Fast::OBJECT_CACHE_REF();
# keep track of classes loaded
my %LOADED_OF = ();
sub new {
@@ -24,7 +25,12 @@ sub new {
};
bless $self, $class;
$self->load_classes() if ($args->{ 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;
}
@@ -32,7 +38,8 @@ sub class_resolver {
my $self = shift;
if (@_) {
$self->{ class_resolver } = shift;
$self->load_classes();
$self->load_classes()
if ! exists $LOADED_OF{ $self->{ class_resolver } };
}
return $self->{ class_resolver };
}
@@ -42,7 +49,8 @@ sub load_classes {
return if $LOADED_OF{ $self->{ class_resolver } };
for (values %{ $self->{ class_resolver }->get_typemap }) {
# requires sorting to make sub-packages load after their parent
for (sort values %{ $self->{ class_resolver }->get_typemap }) {
no strict qw(refs);
my $class = $_;
@@ -50,9 +58,10 @@ sub load_classes {
next if $class eq '__SKIP__';
next if defined *{ "$class\::" }; # check if namespace exists
# Require takes a bareword or a file name - we have to take
# the filname road here...
$class =~s{ :: }{/}xmsg;
$class .= '.pm';
require $class;
require "$class.pm"; ## no critic (RequireBarewordIncludes)
}
$LOADED_OF{ $self->{ class_resolver } } = 1;
}
@@ -99,19 +108,18 @@ sub _initialize {
return;
}
)
: ();
: (
0 => sub { $depth++ },
1 => sub { $depth++ },
);
# use "globals" for speed
my ($_prefix, $_method,
$_class, $_leaf) = ();
my ($_prefix, $_method, $_class, $_leaf) = ();
my $char_handler = sub {
return if (!$_leaf); # we only want characters in leaf nodes
$characters .= $_[1];
# if $_[1] =~m{ [^\s] }xms;
return;
return if (!$_leaf); # we only want characters in leaf nodes
$characters .= $_[1]; # add to characters
return; # return void
};
no strict qw(refs);
@@ -128,15 +136,18 @@ sub _initialize {
return &{$content_check{ $depth }}
if exists $content_check{ $depth };
push @{ $path }, $_[1]; # step down in path
push @{ $path }, $_[1]; # step down in path
return if $skip; # skip inside __SKIP__
# resolve class of this element
$_class = $self->{ class_resolver }->get_class( $path )
or die "Cannot resolve class for "
. join('/', @{ $path }) . " via " . $self->{ class_resolver };
$_class = $self->{ class_resolver }->get_class( $path );
if ($_class eq '__SKIP__') {
if (! defined($_class) and $self->{ strict }) {
die "Cannot resolve class for "
. join('/', @{ $path }) . " via " . $self->{ class_resolver };
}
if (! defined($_class) or ($_class eq '__SKIP__') ) {
$skip = join('/', @{ $path });
$_[0]->setHandlers( Char => undef );
return;
@@ -162,6 +173,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..$#_] });
#
@@ -171,9 +185,25 @@ sub _initialize {
$current = bless \$o, $_class;
}
$current->attr({ @_[2..$#_] }) if (@_ > 2);
# set attributes if there are any
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++;
# TODO: Skip content of anyType / any stuff
return;
},
@@ -193,13 +223,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.
@@ -209,22 +232,37 @@ 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{};
# stop believing we're a leaf node
$_leaf = 0;
# 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
$_leaf = 0; # stop believing we're a leaf node
return;
}
);
@@ -292,11 +330,11 @@ the same terms as perl itself
=head1 Repository information
$Id: $
$Id: MessageParser.pm 851 2009-05-15 22:45:18Z kutterma $
$LastChangedDate: 2008-01-19 13:57:57 +0100 (Sa, 19 Jan 2008) $
$LastChangedRevision: 497 $
$LastChangedDate: 2009-05-16 00:45:18 +0200 (Sa, 16. Mai 2009) $
$LastChangedRevision: 851 $
$LastChangedBy: kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $

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';
our $VERSION = $SOAP::WSDL::VERSION;
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: 851 $
$LastChangedBy: kutterma $
$Id: MessageStreamParser.pm 477 2007-12-24 10:23:52Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
$Id: MessageStreamParser.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
=cut

View File

@@ -1,151 +1,341 @@
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_29};
our $VERSION = $SOAP::WSDL::VERSION;
#
# Import child elements of a WSDL / XML Schema tree into the current tree
#
# Set the targetNamespace of the imported nodes to $import_namespace
#
# SYNOPSIS
#
# $self->_import_children($name, $imported, $imported, $import_namespace)
#
sub _import_children {
my ( $self, $name, $imported, $importer, $import_namespace ) = @_;
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) {
$value_ref = [$value_ref] if ( not ref $value_ref eq 'ARRAY' );
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($_);
}
}
}
sub _import_namespace_definitions {
my $self = shift;
my $arg_ref = shift;
my $importer = $arg_ref->{importer};
my $imported = $arg_ref->{imported};
# import namespace definitions, too
my $importer_ns_of = $importer->get_xmlns();
my %xmlns_of = %{$imported->get_xmlns()};
# it's a hash ref, we can just add to.
# TODO: check whether URI is the better key.
while ( my ( $prefix, $url ) = each %xmlns_of ) {
if ( exists( $importer_ns_of->{$prefix} ) ) {
# warn "$prefix already exists";
next;
}
$importer_ns_of->{$prefix} = $url;
}
}
sub xml_schema_import {
my $self = shift;
my $schema = shift;
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);
# might already be imported - parse_uri just returns in this case
return if not defined $imported;
$self->_import_namespace_definitions( {
importer => $schema,
imported => $imported,
} );
for my $name (qw(type element group attribute attributeGroup)) {
$self->_import_children( $name, $imported, $schema,
$import_namespace );
}
}
sub wsdl_import {
my $self = shift;
my $definitions = shift;
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);
# might already be imported - parse_uri just returns in this case
return if not defined $imported;
$self->_import_namespace_definitions( {
importer => $definitions,
imported => $imported,
} );
for my $name (qw(types message binding portType service)) {
$self->_import_children( $name, $imported, $definitions,
$import_namespace );
}
}
sub _initialize {
my ($self, $parser) = @_;
my ( $self, $parser ) = @_;
# init object data
$self->{ parser } = $parser;
delete $self->{ data };
$self->{parser} = $parser;
delete $self->{data};
# setup local variables for keeping temp data
my $characters = undef;
my $current = undef;
my $list = []; # node list
my $characters = undef;
my $current = undef;
my $list = []; # node list
my $elementFormQualified = 1; # default for WSDLs, schema may override
# TODO skip non-XML Schema namespace tags
$parser->setHandlers(
Start => sub {
my ($parser, $localname, %attrs) = @_;
# handle attrs as list - expat uses dual-vars for looking
# up namespace information, and hash keys don't allow dual vars...
my ( $parser, $localname, @attrs ) = @_;
$characters = q{};
my $action = SOAP::WSDL::TypeLookup->lookup(
$parser->namespace($localname),
$localname
);
my $action =
SOAP::WSDL::TypeLookup->lookup( $parser->namespace($localname),
$localname );
return if not $action;
if ($action->{ type } eq 'CLASS') {
if ( $action->{type} eq 'CLASS' ) {
eval "require $action->{ class }";
croak $@ if ($@);
my $obj = $action->{ class }->new({ parent => $current,
xmlns => { '#default' => $parser->namespace($localname) }
})
->init( _fixup_attrs( $parser, %attrs ) );
my $obj = $action->{class}->new( {
parent => $current,
namespace => $parser->namespace($localname),
defined($current)
? ( xmlns => $current->get_xmlns() )
: ()} )->init( _fixup_attrs( $parser, @attrs ) );
if ($current) {
if ( defined $list->[-1]
&& $list->[-1]->isa('SOAP::WSDL::XSD::Schema') ) {
$elementFormQualified =
$list->[-1]->get_elementFormDefault() eq
'qualified';
}
# inherit namespace, but don't override
$obj->set_targetNamespace( $current->get_targetNamespace() )
if not $obj->get_targetNamespace();
if ($elementFormQualified) {
$obj->set_targetNamespace(
$current->get_targetNamespace() )
if not $obj->get_targetNamespace();
}
# push on parent's element/type list
my $method = "push_$localname";
no strict qw(refs);
$current->$method( $obj );
$current->$method($obj);
# remember element for stepping back
push @{ $list }, $current;
}
else {
$self->{ data } = $obj;
push @{$list}, $current;
}
# set new element (step down)
$current = $obj;
}
elsif ($action->{ type } eq 'PARENT') {
$current->init( _fixup_attrs($parser, %attrs) );
elsif ( $action->{type} eq 'PARENT' ) {
$current->init( _fixup_attrs( $parser, @attrs ) );
}
elsif ($action->{ type } eq 'METHOD') {
my $method = $action->{ method };
elsif ( $action->{type} eq 'METHOD' ) {
my $method = $action->{method};
no strict qw(refs);
# call method with
# - default value ($action->{ value } if defined,
# dereferencing lists
# - the values of the elements Attributes hash
# TODO: add namespaces declared to attributes.
# Expat consumes them, so we have to re-add them here.
$current->$method( defined $action->{ value }
? ref $action->{ value }
? @{ $action->{ value } }
: ($action->{ value })
: _fixup_attrs($parser, %attrs)
);
$current->$method(
defined $action->{value}
? ref $action->{value}
? @{$action->{value}}
: ( $action->{value} )
: _fixup_attrs( $parser, @attrs ) );
}
elsif ( $action->{type} eq 'HANDLER' ) {
my $method = $self->can( $action->{method} );
$method->( $self, $current, @attrs );
}
else {
# TODO replace by hash lookup of known namespaces.
my $namespace = $parser->namespace($localname) || q{};
my $part =
$namespace eq 'http://schemas.xmlsoap.org/wsdl/'
? 'WSDL 1.1'
: 'XML Schema';
warn "$part element <$localname> is not implemented yet"
if ( $localname !~
m{ \A (:? annotation | documentation ) \z }xms );
}
return;
},
Char => sub { $characters .= $_[1]; return; },
Char => sub { $characters .= $_[1]; return; },
End => sub {
my ($parser, $localname) = @_;
my ( $parser, $localname ) = @_;
my $action = SOAP::WSDL::TypeLookup->lookup(
$parser->namespace( $localname ),
$localname
) || {};
my $action =
SOAP::WSDL::TypeLookup->lookup( $parser->namespace($localname),
$localname )
|| {};
return if not ($action->{ type });
if ( $action->{ type } eq 'CLASS' ) {
$current = pop @{ $list };
if ( !defined $list->[-1] ) {
$self->{data} = $current;
return;
}
elsif ($action->{ type } eq 'CONTENT' ) {
my $method = $action->{ method };
return if not( $action->{type} );
if ( $action->{type} eq 'CLASS' ) {
$current = pop @{$list};
if ( defined $list->[-1] && $list->[-1]->isa('SOAP::WSDL::XSD::Schema') ) {
$elementFormQualified = 1;
}
}
elsif ( $action->{type} eq 'CONTENT' ) {
my $method = $action->{method};
# normalize whitespace
$characters =~s{ ^ \s+ (.+) \s+ $ }{$1}xms;
$characters =~s{ \s+ }{ }xmsg;
$characters =~ s{ ^ \s+ (.+) \s+ $ }{$1}xms;
$characters =~ s{ \s+ }{ }xmsg;
no strict qw(refs);
$current->$method( $characters );
$current->$method($characters);
}
return;
}
);
} );
return $parser;
}
# make attrs SAX style
sub _fixup_attrs {
my ($parser, %attrs_of) = @_;
my ( $parser, @attrs ) = @_;
my @attrs_from = map { $_ =
{
Name => $_,
Value => $attrs_of{ $_ },
LocalName => $_
}
} keys %attrs_of;
my @attr_key_from = ();
my @attr_value_from = ();
while (@attrs) {
push @attr_key_from, shift @attrs;
push @attr_value_from, shift @attrs;
}
my @attrs_from;
# add xmlns: attrs. expat eats them.
push @attrs_from, map {
# ignore xmlns=FOO namespaces - must be XML schema
# Other nodes should be ignored somewhere else
($_ eq '#default')
? ()
:
{
Name => "xmlns:$_",
Value => $parser->expand_ns_prefix( $_ ),
#
# add namespaces before attributes: Attributes may be namespace-qualified
#
push @attrs_from, map { {
Name => "xmlns:$_",
Value => $parser->expand_ns_prefix($_),
LocalName => $_
}
} $parser->new_ns_prefixes();
push @attrs_from, map { {
Name => defined $parser->namespace($_)
? $parser->namespace($_) . '|' . $_
: '|' . $_,
Value => shift @attr_value_from, # $attrs_of{ $_ },
LocalName => $_
}
} @attr_key_from;
return @attrs_from;
}
1;
=pod
=head1 NAME
@@ -177,11 +367,11 @@ the same terms as perl itself
=head1 Repository information
$Id: $
$Id: WSDLParser.pm 851 2009-05-15 22:45:18Z kutterma $
$LastChangedDate: 2007-12-24 11:23:52 +0100 (Mo, 24 Dez 2007) $
$LastChangedRevision: 477 $
$LastChangedDate: 2009-05-16 00:45:18 +0200 (Sa, 16. Mai 2009) $
$LastChangedRevision: 851 $
$LastChangedBy: kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $
$HeadURL: https://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';
our $VERSION = $SOAP::WSDL::VERSION;
my %DESERIALIZER = (
'1.1' => 'SOAP::WSDL::Deserializer::XSD',
@@ -16,7 +16,7 @@ sub register {
sub get_deserializer {
my ($self, $args_of_ref) = @_;
$args_of_ref->{ soap_version } ||= '1.1';
# sanity check
die "no deserializer registered for SOAP version $args_of_ref->{ soap_version }"
if not exists ($DESERIALIZER{ $args_of_ref->{ soap_version } });
@@ -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';
our $VERSION = $SOAP::WSDL::VERSION;
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';
our $VERSION = $SOAP::WSDL::VERSION;
my %SERIALIZER = (
'1.1' => 'SOAP::WSDL::Serializer::XSD',
@@ -16,7 +16,7 @@ sub register {
sub get_serializer {
my ($self, $args_of_ref) = @_;
$args_of_ref->{ soap_version } ||= '1.1';
# sanity check
die "no serializer registered for SOAP version $args_of_ref->{ soap_version }"
if not exists ($SERIALIZER{ $args_of_ref->{ soap_version } });
@@ -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: 391 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Serializer.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
$Id: Serializer.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://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;
our $VERSION = $SOAP::WSDL::VERSION;
our $VERSION='2.00_25';
# class data
my %registered_transport_of = ();
# Local constants
@@ -12,7 +10,7 @@ my %registered_transport_of = ();
my %SOAP_LITE_TRANSPORT_OF = (
ftp => 'SOAP::Transport::FTP',
http => 'SOAP::Transport::HTTP',
https => 'SOAP::Transport::HTTPS',
https => 'SOAP::Transport::HTTP',
mailto => 'SOAP::Transport::MAILTO',
'local' => 'SOAP::Transport::LOCAL',
jabber => 'SOAP::Transport::JABBER',
@@ -32,14 +30,17 @@ sub register {
}
sub get_transport {
my ($class, $scheme, %attrs) = @_;
my ($class, $url, %attrs) = @_;
$scheme =~s{ \A ([^\:]+) \: .+ }{$1}smx;
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 }"
$registered_transport_of{ $scheme }->can('new') 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
my $protocol_class = $SOAP_LITE_TRANSPORT_OF{ $scheme } . '::Client';
$protocol_class->can('new')
or eval "require $SOAP_LITE_TRANSPORT_OF{ $scheme }"
or last SOAP_Lite;
# 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 }::" }
$SOAP_WSDL_TRANSPORT_OF{ $scheme }->can('new')
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 );
@@ -96,12 +99,12 @@ SOAP::WSDL::Factory::Transport - Factory for retrieving transport objects
# in transport class:
package MyWickedTransport;
use SOAP::WSDL::Factory::Transport;
# register class as transport module for httpr and https
# (httpr is "reliable http", a protocol developed by IBM).
SOAP::WSDL::Factory::Transport->register( 'httpr' , __PACKAGE__ );
SOAP::WSDL::Factory::Transport->register( 'https' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Transport serves as factory for retrieving transport objects for
@@ -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
@@ -207,10 +210,10 @@ classes in one file, and to follow this naming scheme:
Module name:
"SOAP::Transport::" . uc($scheme)
Client class (additional package in module):
"SOAP::Transport::" . uc($scheme) . "::Client"
Server class (additional package in module):
"SOAP::Transport::" . uc($scheme) . "::Client"
@@ -240,9 +243,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 459 $
$Rev: 851 $
$LastChangedBy: kutterma $
$Id: Transport.pm 459 2007-12-16 16:00:14Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $
$Id: Transport.pm 851 2009-05-15 22:45:18Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $
=cut

View File

@@ -0,0 +1,272 @@
package SOAP::WSDL::Generator::Iterator::WSDL11;
use strict; use warnings;
use Class::Std::Fast;
our $VERSION = $SOAP::WSDL::VERSION;
my %definitions_of :ATTR(:name<definitions> :default<[]>);
my %nodes_of :ATTR(:name<nodes> :default<[]>);
# memoization attributes
my %portType_of :ATTR();
my %types_of :ATTR();
my %METHOD_OF = (
'SOAP::WSDL::Definitions' => 'get_service',
'SOAP::WSDL::Service' => 'get_port',
'SOAP::WSDL::Port' => sub {
my ($self, $node) = @_;
return if ! $node->first_address()
or ! $node->first_address()->isa('SOAP::WSDL::SOAP::Address');
return [ $self->get_definitions()
->find_binding( $node->expand( $node->get_binding() ) ) || () ];
},
'SOAP::WSDL::Binding' => sub {
my ($self, $node) = @_;
# remember referenced portType
$portType_of{ ident $self } = $self->get_definitions()
->find_portType( $node->expand( $node->get_type ) )
or return [];
return $node->get_operation();
},
'SOAP::WSDL::Operation' => sub {
my ($self, $node) = @_;
my $name = $node->get_name();
# get the equally named operation from the portType
my ($op) = grep { $_->get_name() eq $name }
@{ $portType_of{ ident $self }->get_operation() }
or return [];
return [ @{ $op->get_input }, @{ $op->get_output }, @{ $op->get_fault } ]
},
'SOAP::WSDL::OpMessage' => sub {
my ($self, $node) = @_;
return if ( ref $node->get_parent() eq 'SOAP::WSDL::Binding' ); # we're in binding
# TODO maybe allow more messages && overloading by specifying name
return [ $self->get_definitions()->find_message(
$node->expand( $node->get_message() )
) || () ];
},
'SOAP::WSDL::Message' => 'get_part',
'SOAP::WSDL::Part' => sub {
my ($self, $node) = @_;
my $ident = ident $self;
my $types = $types_of{ $ident } = $definitions_of{ $ident }->get_types()->[0]
or return [];
return [
# If we have a type, this type is to be used in document/literal
# as global type. However this is forbidden, at least by WS-I.
# We should store the style/encoding somewhere, and regard it.
# TODO: auto-generate element for RPC bindings
$node->get_type()
? do {
die "unsupported global type <"
. $node->get_type . "> found in part <". $node->get_name() . ">\n"
. "Looks like a rpc/literal WSDL, which is not supported by SOAP::WSDL\n";
## use this once we can auto-generate an element for RPC bindings
# $types->find_type( $node->expand($node->get_type) )
}
: (),
$node->get_element()
? $types->find_element( $node->expand($node->get_element) )
: (),
];
},
);
sub init {
my ($self, $arg_of) = @_;
my $ident = ident $self;
undef $portType_of{ $ident };
undef $types_of{ $ident };
$nodes_of{ $ident } = [
exists($arg_of->{ node })
? $arg_of->{ node }
: $definitions_of{ ident $self }
];
}
sub get_next {
my $self = shift;
my $ident = ident $self;
my $node = shift @{ $nodes_of{ $ident }};
return if ! defined $node;
unshift @{ $nodes_of{ $ident }}, @{ $self->get_nextNodes( $node ) || [] };
return $node;
}
sub get_nextNodes {
my ($self, $node) = @_;
my $method = $METHOD_OF{ ref $node }
or return [];
return (ref($method) eq 'CODE')
? $method->( $self, $node )
: $node->can($method)->( $node );
}
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::Generator::Iterator::WSDL11 - WSDL 1.1 Iterator
=head1 SYNOPSIS
my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new({
definitions => $wsdl
});
$iter->init();
while (my $node = $iter->get_next()) {
# do something with node - possibly call _accept with a visitor on it...
}
=head1 DESCRIPTION
Iterator for walking a WSDL 1.1 definition.
The iterator performs a depth-first search along the following path:
service
port
binding
operation
input/output/fault of operation in portType
message
part
type/element in XML schema
If you wonder about this path: This is how to look up which XML Schema element
is associated with a operation from a service/port.
=head2 Example
The nodes are returned in the order denoted in the following example:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 1 -->
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HelloWorld"
targetNamespace="urn:HelloWorld"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<s:schema elementFormDefault="qualified" targetNamespace="urn:HelloWorld">
<!-- 9 -->
<s:element name="sayHello">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="givenName" type="s:string" nillable="1" />
</s:sequence>
<s:attribute name="testAttr" type="s:string" use="optional"></s:attribute>
</s:complexType>
</s:element>
<!-- 13 -->
<s:element name="sayHelloResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="sayHelloResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</types>
<!-- 7 -->
<message name="sayHelloSoapIn">
<!-- 8 -->
<part name="parameters" element="s0:sayHello" />
</message>
<!-- 11 -->
<message name="sayHelloSoapOut">
<!-- 12 -->
<part name="parameters" element="s0:sayHelloResponse" />
</message>
<portType name="Service1Soap">
<operation name="sayHello">
<!-- 6 -->
<input message="s0:sayHelloSoapIn" />
<!-- 10 -->
<output message="s0:sayHelloSoapOut" />
</operation>
</portType>
<!-- 4 -->
<binding name="Service1Soap" type="s0:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<!-- 5 -->
<operation name="sayHello">
<soap:operation soapAction="urn:HelloWorld#sayHello"
style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<!-- 2 -->
<service name="Service1">
<!-- 3 -->
<port name="Service1Soap" binding="s0:Service1Soap">
<soap:address
location="http://localhost:81/soap-wsdl-test/helloworld.pl" />
</port>
</service>
</definitions>
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.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2008 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 239 $
$LastChangedBy: kutterma $
$Id: Client.pm 239 2007-09-11 09:45:42Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
=cut

View File

@@ -0,0 +1,145 @@
package SOAP::WSDL::Generator::PrefixResolver;
use strict; use warnings;
use Class::Std::Fast::Storable;
our $VERSION = $SOAP::WSDL::VERSION;
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) = @_;
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;
__END__
=pod
=head1 NAME
SOAP::WSDL::Generator::PrefixResolver - prefixes for different classes
=head1 SYNOPSIS
If you want to create your custom prefix resolver:
package MyPrefixResolver;
use strict; use warnings;
use base qw(SOAP::WSDL::Generator::PrefixResolver);
sub resolve_prefix {
my ($self, $type, $namespace, $node) = @_;
# return something special
return $self->SUPER::resolve_prefix($type, $namespace, $node);
}
When generating code:
use MyPrefixResolver;
use SOAP::WSDL::Generator::XSD;
my $generator = SOAP::WSDL::Generator::Template::XSD->new({
prefix_resolver_class => 'MyPrefixResolver',
});
=head1 DESCRIPTION
Prefix resolver class for SOAP::WSDL's code generator. You may subclass it to
apply some custom prefix resolving logic.
Subclasses must implement the following methods:
=over
=item * resolve_prefix
sub resolve_prefix {
my ($self, $namespace, $node) = @_;
# ...
}
resolve_prefix is expected to return a (perl class) prefix. It is called with
the following parameters:
NAME DESCRIPTION
-----------------------------------------------------------------------------
type One of (server|interface|typemap|type|element|attribute)
namespace The targetNamespace of the node to generate a prefix for.
node The node to generate a prefix for
You usually just need type and namespace for prefix resolving. node is
provided for rather funky setups, where you have to choose different prefixes
based on type names or whatever.
Node may be of any of the following classes:
SOAP::WSDL::Service
SOAP::WSDL::XSD::Attribute
SOAP::WSDL::XSD::Element
SOAP::WSDL::XSD::Type
Note that both namespace and node may be undef - you should test for
definedness before doing anything fancy with them.
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.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 583 $
$LastChangedBy: kutterma $
$Id: $
$HeadURL: $
=cut

View File

@@ -1,21 +1,26 @@
package SOAP::WSDL::Generator::Template;
use strict;
use Template;
use strict; use warnings;
use Template 2.18;
use Class::Std::Fast::Storable;
use Carp;
use SOAP::WSDL::Generator::PrefixResolver;
our $VERSION=q{2.00_25};
our $VERSION = $SOAP::WSDL::VERSION;
my %tt_of :ATTR(:get<tt>);
my %definitions_of :ATTR(:name<definitions> :default<()>);
my %server_prefix_of :ATTR(:name<server_prefix> :default<MyServer>);
my %interface_prefix_of :ATTR(:name<interface_prefix> :default<MyInterfaces>);
my %typemap_prefix_of :ATTR(:name<typemap_prefix> :default<MyTypemaps>);
my %type_prefix_of :ATTR(:name<type_prefix> :default<MyTypes>);
my %element_prefix_of :ATTR(:name<element_prefix> :default<MyElements>);
my %INCLUDE_PATH_of :ATTR(:name<INCLUDE_PATH> :default<()>);
my %EVAL_PERL_of :ATTR(:name<EVAL_PERL> :default<0>);
my %RECURSION_of :ATTR(:name<RECURSION> :default<0>);
my %OUTPUT_PATH_of :ATTR(:name<OUTPUT_PATH> :default<.>);
my %definitions_of :ATTR(:name<definitions> :default<()>);
my %server_prefix_of :ATTR(:name<server_prefix> :default<MyServer>);
my %interface_prefix_of :ATTR(:name<interface_prefix> :default<MyInterfaces>);
my %typemap_prefix_of :ATTR(:name<typemap_prefix> :default<MyTypemaps>);
my %type_prefix_of :ATTR(:name<type_prefix> :default<MyTypes>);
my %element_prefix_of :ATTR(:name<element_prefix> :default<MyElements>);
my %attribute_prefix_of :ATTR(:name<attribute_prefix> :default<MyAttributes>);
my %INCLUDE_PATH_of :ATTR(:name<INCLUDE_PATH> :default<()>);
my %EVAL_PERL_of :ATTR(:name<EVAL_PERL> :default<0>);
my %RECURSION_of :ATTR(:name<RECURSION> :default<0>);
my %OUTPUT_PATH_of :ATTR(:name<OUTPUT_PATH> :default<.>);
my %prefix_resolver_class_of :ATTR(:name<prefix_resolver_class> :default<SOAP::WSDL::Generator::PrefixResolver>);
sub START {
my ($self, $ident, $arg_ref) = @_;
@@ -25,29 +30,79 @@ sub _process :PROTECTED {
my ($self, $template, $arg_ref, $output) = @_;
my $ident = ident $self;
$tt_of{$ident} = Template->new(
# always create a new Template object to
# force re-loading of plugins.
my $tt = Template->new(
DEBUG => 1,
EVAL_PERL => $EVAL_PERL_of{ $ident },
RECURSION => $RECURSION_of{ $ident },
INCLUDE_PATH => $INCLUDE_PATH_of{ $ident },
OUTPUT_PATH => $OUTPUT_PATH_of{ $ident },
PLUGIN_BASE => 'SOAP::WSDL::Generator::Template::Plugin',
)
if (not $tt_of{ $ident });
or die Template->error();
$tt_of{ $ident }->process( $template,
$tt->process( $template,
{
context => {
prefix_resolver => $prefix_resolver_class_of{ $$self }->new({
namespace_prefix_map => {
'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin',
},
namespace_map => {
},
prefix => {
interface => $self->get_interface_prefix,
element => $self->get_element_prefix,
attribute => $self->get_attribute_prefix,
server => $self->get_server_prefix,
type => $self->get_type_prefix,
typemap => $self->get_typemap_prefix,
}
}),
},
definitions => $self->get_definitions,
interface_prefix => $self->get_interface_prefix,
server_prefix => $self->get_server_prefix,
type_prefix => $self->get_type_prefix,
typemap_prefix => $self->get_typemap_prefix,
TYPE_PREFIX => $self->get_type_prefix,
element_prefix => $self->get_element_prefix,
NO_POD => delete $arg_ref->{ NO_POD } ? 1 : 0 ,
%{ $arg_ref }
},
$output)
or die $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt_of{ $ident }->error();
or croak $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error();
}
1;
1;
=pod
=head1 NAME
SOAP::WSDL::Generator::Template - Template-based code generator
=head1 DESCRIPTION
SOAP::WSDL's template based code generator
Base class for writing template based generators
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 LICENSE AND COPYRIGHT
Copyright 2008, 2009 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 Repository information
$Id: WSDLParser.pm 770 2009-01-24 22:55:54Z kutterma $
$LastChangedDate: 2009-01-24 23:55:54 +0100 (Sa, 24 Jan 2009) $
$LastChangedRevision: 770 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $

View File

@@ -0,0 +1,218 @@
package SOAP::WSDL::Generator::Template::Plugin::XSD;
use strict;
use warnings;
use Carp qw(confess);
use Class::Std::Fast::Storable constructor => 'none';
use Scalar::Util qw(blessed);
our $VERSION = $SOAP::WSDL::VERSION;
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)
my ($class, $context, @arg_from) = @_;
my $stash = $context->stash();
my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class;
$self->set_prefix_resolver( $stash->{ context }->{ prefix_resolver });
$self->set_definitions( $stash->{ definitions });
return $self; # returns 'MyPlugin'
}
sub new {
return shift if ref $_[0];
my ($class, $arg_ref) = @_;
my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class;
$self->set_prefix_resolver( $arg_ref->{ prefix_resolver });
$self->set_definitions( $arg_ref->{ definitions });
return $self; # returns 'MyPlugin'
}
sub _get_prefix {
my ($self, $type, $node) = @_;
my $namespace = defined ($node)
? ref($node)
? $node->get_targetNamespace()
: $node
: undef;
return $self->get_prefix_resolver()->resolve_prefix(
$type,
$namespace,
ref($node)
? $node
: undef
);
}
sub create_xsd_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') #. '::'
. $node->get_name();
return $self->perl_name( $name );
}
sub create_server_name {
my ($self, $server, $port) = @_;
my $port_name = $port->get_name();
$port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x;
my $name = join( q{},
$self->_get_prefix('server', $server),
join( '::', $server->get_name(), $port_name)
);
return $self->perl_name( $name );
}
sub create_interface_name {
my ($self, $server, $port) = @_;
my $port_name = $port->get_name();
$port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x;
my $name = join( q{},
$self->_get_prefix('interface', $server),
join( '::', $server->get_name(), $port_name )
);
return $self->perl_name( $name );
}
sub _resolve_prefix {
my ($self, $node) = @_;
if ($node->isa('SOAP::WSDL::XSD::Builtin')) {
return $self->_get_prefix('type', $node)
}
if ( $node->isa('SOAP::WSDL::XSD::SimpleType')
or $node->isa('SOAP::WSDL::XSD::ComplexType')
) {
return $self->_get_prefix('type', $node);
}
if ( $node->isa('SOAP::WSDL::XSD::Element') ) {
return $self->_get_prefix('element', $node);
}
if ( $node->isa('SOAP::WSDL::XSD::Attribute') ) {
return $self->_get_prefix('attribute', $node);
}
}
sub perl_name {
my $self = shift;
my $name = shift;
$name =~s{\-}{_}xmsg;
$name =~s{\.}{::}xmsg;
return $name;
}
sub perl_var_name {
my $self = shift;
my $name = shift;
$name =~s{\-}{_}xmsg;
$name =~s{\.}{__}xmsg;
return $name;
}
sub create_subpackage_name {
my $self = shift;
my $arg_ref = shift;
my $type = ref $arg_ref eq 'HASH' ? $arg_ref->{ value } : $arg_ref;
my @name_from = $type->get_name() || (); ;
# search for top node in tree (the one directly below the Schema)
my $parent = $type;
my $top_node = $parent;
if (! $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema') ) {
NAMES: while ($parent = $parent->get_parent()) {
$top_node = $parent;
last NAMES if $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema');
# skip empty names - atomic types have no name...
unshift @name_from, $parent->get_name()
if $parent->get_name();
}
}
# create name for top node
die "No top node found" 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) : () );
# replace dots by :: in name - subpackage names may include dots, too
$package_name =~s{\.}{::}xg;
return $package_name;
}
sub create_xmlattr_name {
return join '::', shift->create_subpackage_name(shift), 'XmlAttr';
}
sub element_name {
my $self = shift;
my $element = shift;
confess "no element object" unless blessed $element;
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
=head1 NAME
SOAP::WSDL::Generator::Template::Plugin::XSD - Template plugin for the XSD generator
=head1 METHODS
=head2 perl_name
XSD.perl_name(element.get_name);
Converts a XML name into a valid perl name (valid for subroutines, variables
or the like).
perl_name takes a crude approach by just replacing . and - (dot and dash)
with a underscore. This may or may not be sufficient, and may or may not
provoke collisions in your XML names.
=head1 LICENSE AND COPYRIGHT
Copyright 2008 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under the same
terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 564 $
$LastChangedBy: kutterma $
$Id: ComplexType.pm 564 2008-02-23 13:31:39Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm $
=cut

View File

@@ -1,18 +1,19 @@
package SOAP::WSDL::Generator::Template::XSD;
use strict;
use Template;
use strict; use warnings;
use Template 2.18;
use Class::Std::Fast::Storable;
use File::Basename;
use File::Spec;
our $VERSION = q{2.00_27};
our $VERSION = $SOAP::WSDL::VERSION;
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<({})>);
my %silent_of :ATTR(:name<silent> :default<0>);
sub BUILD {
my ($self, $ident, $arg_ref) = @_;
@@ -46,93 +47,105 @@ 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;
$self->generate_typelib( $opt );
# $self->generate_interface( $opt );
$self->generate_typemap( $opt );
}
sub generate_typelib {
my ($self, $arg_ref) = @_;
# $output_of{ ident $self } = "";
my @schema = exists $arg_ref->{ schema }
? @{ $arg_ref->{schema} }
: @{ $self->get_definitions()->first_types()->get_schema() };
for my $type (map { @{ $_->get_type() } , @{ $_->get_element() } } @schema[1..$#schema] ) {
for my $type (map {
@{ $_->get_type() } ,
@{ $_->get_element() },
@{ $_->get_attribute() }
} @schema[1..$#schema] ) {
$type->_accept( $self );
}
# return $output_of{ ident $self };
return;
}
sub _generate_interface {
my $self = shift;
my $arg_ref = shift;
my $template_name = delete $arg_ref->{ template_name };
my $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
next if not $port->first_address;
next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address');
my $port_name = $port->get_name;
$port_name =~s{ \A .+\. }{}xms;
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename(
$self->get_name_resolver()->can($name_method)->(
$self->get_name_resolver(),
$service,
$port,
));
print "Creating interface class $output\n"
if not $silent_of{ident $self};
$self->_process($template_name,
{
service => $service,
port => $port,
NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 ,
},
$output, binmode => ':utf8');
}
}
}
sub generate_server {
my $self = shift;
my $ident = ident $self;
my $arg_ref = shift;
for my $service (@{ $self->get_definitions->get_service }) {
for my $port (@{ $service->get_port() }) {
# Skip ports without (known) address
next if not $port->first_address;
next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address');
my $port_name = $port->get_name;
$port_name =~s{ \A .+\. }{}xms;
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename(
$self->get_server_prefix(),
$service->get_name(),
$port_name,
);
print "Creating interface class $output\n";
$self->_process('Server.tt',
{
service => $service,
port => $port,
NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 ,
},
$output, binmode => ':utf8');
}
}
my ($self, $arg_ref) = @_;
$arg_ref->{ template_name } = 'Server.tt';
$arg_ref->{ name_method } = 'create_server_name';
$self->_generate_interface($arg_ref);
}
sub generate_interface {
my $self = shift;
my $ident = ident $self;
my $arg_ref = shift;
for my $service (@{ $self->get_definitions->get_service }) {
for my $port (@{ $service->get_port() }) {
# Skip ports without (known) address
next if not $port->first_address;
next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address');
my $port_name = $port->get_name;
$port_name =~s{ \A .+\. }{}xms;
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename(
$self->get_interface_prefix(),
$service->get_name(),
$port_name,
);
print "Creating interface class $output\n";
$self->_process('Interface.tt',
{
service => $service,
port => $port,
NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 ,
},
$output, binmode => ':utf8');
}
}
sub generate_client {
my ($self, $arg_ref) = @_;
$arg_ref->{ template_name } = 'Interface.tt';
$arg_ref->{ name_method } = 'create_interface_name';
$self->_generate_interface($arg_ref);
}
sub generate_interface;
*generate_interface = \&generate_client;
sub generate_typemap {
my ($self, $arg_ref) = @_;
my $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new({
type_prefix => $self->get_type_prefix(),
element_prefix => $self->get_element_prefix(),
@@ -144,14 +157,25 @@ sub generate_typemap {
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
%{ $typemap_of{ident $self }},
}
},
resolver => $self->get_name_resolver(),
});
use SOAP::WSDL::Generator::Iterator::WSDL11;
my $iterator = SOAP::WSDL::Generator::Iterator::WSDL11->new({
definitions => $self->get_definitions });
for my $service (@{ $self->get_definitions->get_service }) {
$visitor->visit_Service( $service );
$iterator->init({ node => $service });
while (my $node = $iterator->get_next()) {
$node->_accept( $visitor );
}
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename( $self->get_typemap_prefix(), $service->get_name() );
print "Creating typemap class $output\n";
: $self->_generate_filename( $self->get_name_resolver()->create_typemap_name($service) );
print "Creating typemap class $output\n"
if not $silent_of{ident $self};
$self->_process('Typemap.tt',
{
service => $service,
@@ -163,19 +187,28 @@ 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;
return "$name.pm";
}
sub visit_XSD_Attribute {
my ($self, $attribute) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($attribute) );
$self->_process('attribute.tt', { attribute => $attribute } , $output);
}
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) );
warn "Creating element class $output \n"
if not $silent_of{ ident $self};
$self->_process('element.tt', { element => $element } , $output);
}
@@ -183,7 +216,9 @@ 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) );
warn "Creating simpleType class $output \n"
if not $silent_of{ ident $self};
$self->_process('simpleType.tt', { simpleType => $type } , $output);
}
@@ -191,8 +226,112 @@ 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) );
warn "Creating complexType class $output \n"
if not $silent_of{ ident $self};
$self->_process('complexType.tt', { complexType => $type } , $output);
}
1;
1;
=pod
=head1 NAME
SOAP::WSDL::Generator::Template::XSD - XSD code generator
=head1 DESCRIPTION
SOAP::WSDL's XSD code generator
=head1 SYNOPSIS
See L<wsdl2perl.pl|wsdl2perl.pl> for an example on how to use this class.
=head1 METHODS
=head2 new
Constructor.
Options (Options can also be set via set_OPTION methods):
=over
=item * silent
Suppress warnings about what's being generated
=back
=head2 generate
Shortcut for calling L<generate_typelib> and L<generate_client>
=head2 generate_client
Generates a client interface
=head2 generate_server
Generates a server class
=head2 generate_typelib
Generates type and element classes
=head2 generate_typemap
Generate a typemap class required by SOAP::WSDL's MessageParser
=head2 generate_interface
(Deprecated) alias for generate_client
=head2 get_name_resolver
Returns a name resolver template plugin
=head2 visit_XSD_Attribute
Visitor method for SOAP::WSDL::XSD::Attribute. Should be factored out into
visitor class.
=head2 visit_XSD_ComplexType
Visitor method for SOAP::WSDL::XSD::ComplexType. Should be factored out into
visitor class.
=head2 visit_XSD_Element
Visitor method for SOAP::WSDL::XSD::Element. Should be factored out into
visitor class.
=head2 visit_XSD_SimpleType
Visitor method for SOAP::WSDL::XSD::SimpleType. Should be factored out into
visitor class.
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 LICENSE AND COPYRIGHT
Copyright 2008, 2009 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 Repository information
$Id: WSDLParser.pm 770 2009-01-24 22:55:54Z kutterma $
$LastChangedDate: 2009-01-24 23:55:54 +0100 (Sa, 24 Jan 2009) $
$LastChangedRevision: 770 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $

View File

@@ -1,7 +1,5 @@
[% interface_name = interface_prefix _ '::'
_ service.get_name.replace('\.', '::') _ '::'
_ port.get_name.replace('^.+\.','');
interface_name = interface_name.replace('-','_'); -%]
[% USE XSD -%]
[% interface_name = XSD.create_interface_name(service, port) -%]
package [% interface_name %];
use strict;
use warnings;
@@ -10,20 +8,22 @@ use Scalar::Util qw(blessed);
use base qw(SOAP::WSDL::Client::Base);
# only load if it hasn't been loaded before
require [% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]
if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]->can('get_class');
require [% XSD.create_typemap_name(service) %]
if not [% XSD.create_typemap_name(service) %]->can('get_class');
sub START {
$_[0]->set_proxy('[% port.first_address.get_location %]') if not $_[2]->{proxy};
$_[0]->set_class_resolver('[% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]')
$_[0]->set_class_resolver('[% XSD.create_typemap_name(service) %]')
if not $_[2]->{class_resolver};
$_[0]->set_prefix($_[2]->{use_prefix}) if exists $_[2]->{use_prefix};
}
[% binding = definitions.find_binding( port.expand( port.get_binding ) );
FOREACH operation = binding.get_operation;
%][% INCLUDE Interface/Operation.tt %]
[%
[%
END;
%]
@@ -48,12 +48,12 @@ __END__
use [% interface_name %];
my $interface = [% interface_name %]->new();
my $response;
[% FOREACH operation = binding.get_operation;
%] $response = $interface->[% operation.get_name %]();
[% END %]
[% head1 %] DESCRIPTION
@@ -82,7 +82,6 @@ All arguments are forwarded to L<SOAP::WSDL::Client|SOAP::WSDL::Client>.
[% INCLUDE Interface/POD/method_info.tt %]
[% FOREACH operation = binding.get_operation;
%][% INCLUDE Interface/POD/Operation.tt %]
[% END %]
@@ -91,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

@@ -1,14 +1,12 @@
[% RETURN IF NOT item;
type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name );
port_op = type.find_operation( type.get_targetNamespace, operation.get_name );
message = definitions.find_message( port_op.first_input.expand( port_op.first_input.get_message ) );
part_from = message.get_part;
PERL %]
my $item = $stash->{ item };
my $def = $stash->{ definitions };
my $part_from = $stash->{ part_from };
my $type_prefix = $stash->{ type_prefix };
my $element_prefix = $stash->{ element_prefix };
my $part_from = $stash->{ message }->get_part();
my @body_part_from = split m{\s}, $item->get_parts;
@@ -17,22 +15,25 @@
@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 {
my $name;
($name = $part->get_element)
? do {
$name =~s{ ^[^:]+: }{}xms;
$element_prefix . '::' . $name;
}
my $element = $def->first_types->find_element($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
$type_prefix . '::' . $name;
}
my $element = $def->first_types->find_type($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: die "input must have either type or element"
}
: ()
@@ -44,13 +45,15 @@
my $name;
($name = $part->get_element)
? do {
$name =~s{ ^[^:]+: }{}xms;
"$element_prefix\::$name"
}
my $element = $def->first_types->find_element($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
"$type_prefix\::$name"
my $element = $def->first_types->find_type($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: die "input must have either type or element";
} @{ $part_from };
@@ -63,7 +66,10 @@
$stash->{ parts } = \@parts;
[% END %]
'use' => '[% item.get_use %]',
namespace => '[% item.get_namespace %]',
encodingStyle => '[% item.get_encodingStyle %]',
parts => [qw( [% parts.join(' ') %] )],
[% IF item.get_use != 'literal';
THROW NOT_SUPPORTED "Body: SOAP::WSDL supports literal encoding only - ${ item.get_use } found";
END %]
'use' => '[% item.get_use %]',
namespace => '[% item.get_namespace %]',
encodingStyle => '[% item.get_encodingStyle %]',
parts => [qw( [% parts.join(' ') %] )],

View File

@@ -11,27 +11,34 @@
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)
? do {
$name =~s{ ^[^:]+: }{}xms;
$element_prefix . '::' . $name;
my $element = $def->first_types->find_element($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
$type_prefix . '::' . $name;
}
my $element = $def->first_types->find_type($part->expand($name));
my $resolver = $context->plugin('XSD');
$resolver->create_xsd_name($element);
}
: die "input must have either type or element"
};
$stash->{ part_class } = $part_class;
[% END;
%]
%]
[% IF item.get_use != 'literal';
THROW NOT_SUPPORTED "Header: SOAP::WSDL supports literal encoding only - ${ item.get_use } found";
END %]
'use' => '[% item.get_use %]',
namespace => '[% item.get_namespace %]',
encodingStyle => '[% item.get_encodingStyle %]',

View File

@@ -4,7 +4,12 @@ sub [% operation.get_name %] {
return $self->SUPER::call({
operation => '[% operation.get_name %]',
soap_action => '[% operation.first_operation.get_soapAction %]',
style => '[% operation.get_style || binding.get_style %]',
style => [% style = operation.first_operation.get_style || binding.get_style;
IF style != "document";
THROW NOT_SUPPORTED "SOAP::WSDL supports document encoding only - $style found";
END;
-%]
'[% style %]',
body => {
[% INCLUDE Interface/Body.tt( item = operation.first_input.first_body ); %]
},

View File

@@ -4,7 +4,16 @@
[% type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name );
port_op.get_documentation %]
port_op.get_documentation();
$interface->[% operation.get_name %]([% INCLUDE Interface/POD/Message.tt %] );
# for now we only document the first response part - document/literal
# doesn't allow more.
response_name = port_op.first_output.get_message();
response_part = definitions.find_message( port_op.first_output.expand( response_name ) ).get_part();
response_body_element = definitions.first_types.find_element( response_part.0.expand( response_part.0.get_element ) );
response_body_class = XSD.create_xsd_name(response_body_element);
%]
Returns a L<[% response_body_class %]|[% response_body_class %]> object.
$response = $interface->[% operation.get_name %]([% INCLUDE Interface/POD/Message.tt %] );

View File

@@ -5,3 +5,12 @@ of the corresponding class can be passed instead of the marked hash ref.
You may pass any combination of objects, hash and list refs to these
methods, as long as you meet the structure.
List items (i.e. multiple occurences) are not displayed in the synopsis.
You may generally pass a list ref of hash refs (or objects) instead of a hash
ref - this may result in invalid XML if used improperly, though. Note that
SOAP::WSDL always expects list references at maximum depth position.
XML attributes are not displayed in this synopsis and cannot be set using
hash refs. See the respective class' documentation for additional information.

View File

@@ -0,0 +1,2 @@
[% node.get_annotation.0.get_documentation %]

View File

@@ -1,7 +1,6 @@
[% server_name = server_prefix _ '::'
_ service.get_name.replace('\.', '::') _ '::'
_ port.get_name.replace('^.+\.','');
server_name = server_name.replace('-','_'); -%]
[% USE XSD;
server_name = XSD.create_server_name(service, port);
-%]
package [% server_name %];
use strict;
use warnings;
@@ -10,8 +9,8 @@ use Scalar::Util qw(blessed);
use base qw(SOAP::WSDL::Client::Base);
# only load if it hasn't been loaded before
require [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]
if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]->can('get_class');
require [% XSD.create_typemap_name(service) %]
if not [% XSD.create_typemap_name(service) %]->can('get_class');
my %transport_class_of :ATTR(:name<transport_class> :default<SOAP::WSDL::Server::CGI>);
my %transport_of :ATTR(:name<transport> :default<()>);
@@ -31,13 +30,13 @@ sub START {
or die "Cannot load transport class $transport_class_of{ $ident }: $@";
$transport_of{ $ident } = $transport_class_of{ $ident }->new({
action_map_ref => $action_map_ref,
class_resolver => '[% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]',
class_resolver => '[% XSD.create_typemap_name(service) %]',
dispatch_to => $dispatch_to{ $ident },
});
}
sub handle {
$transport_of{ ${ $_[0] } }->handle();
$transport_of{ ${ $_[0] } }->handle(@_[1..$#_]);
}
1;
@@ -103,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

@@ -3,7 +3,7 @@
#element;
#STOP;
-%]
[% element_prefix %]::[% element.get_name.replace('\.', '::') %]->new([%
[% XSD.create_xsd_name(element) %]->new([%
type = element.first_complexType || element.first_simpleType || definitions.first_types.find_type(
element.expand( element.get_type ) );
INCLUDE Interface/POD/Type.tt; %]

View File

@@ -1,4 +1,5 @@
package [% typemap_prefix %]::[% service.get_name.replace('\.','::') %];
[% USE XSD %]
package [% XSD.create_typemap_name(service) %];
use strict;
use warnings;
@@ -6,7 +7,6 @@ our [% USE Dumper(varname = 'typemap_'); Dumper.dump( typemap ) %];
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap_1->{ $name };
}
@@ -27,7 +27,7 @@ __END__
[% head1 %] NAME
[% typemap_prefix %]::[% service.get_name.replace('\.','::').replace('-', '_') %]; - typemap for ::[% service.get_name %];
[% XSD.create_typemap_name(service) %] - typemap for [% service.get_name %]
[% head1 %] DESCRIPTION

View File

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

View File

@@ -0,0 +1,83 @@
[% USE XSD(context) %]
package [% XSD.create_xsd_name(attribute) %];
use strict;
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { '[% attribute.get_targetNamespace %]' }
__PACKAGE__->__set_name('[% attribute.get_name %]');
__PACKAGE__->__set_ref([% IF attribute.get_ref; %]'[% attribute.get_ref %]'[% END %]);
[%- IF (type_name = attribute.get_type); -%]
use base qw(
SOAP::WSDL::XSD::Typelib::Attribute
[% type = definitions.get_types.0.find_type(attribute.expand(type_name));
IF ! type;
THROW NOT_FOUND "type " _ type_name _ " not found in attribute " _ attribute.get_name;
END;
XSD.create_xsd_name(type) %]
);
}
[%- ELSIF (ref = attribute.get_ref);
ref_from = ref.split(':');
-%]
# attribute ref="[% ref %]"
use base qw(
[% ref_element = definitions.get_types.0.find_attribute(attribute.expand(ref));
XSD.create_xsd_name( ref_element ); %]
);
}
[%- ELSIF (simpleType = attribute.first_simpleType) %]
# atomic simpleType: <attribute><simpleType
use base qw(
SOAP::WSDL::XSD::Typelib::Attribute
);
[% INCLUDE simpleType/contentModel.tt -%]
}
[% END %]
1;
[%# work around for CPAN's indexer, which gets disturbed by pod in templates -%]
[% pod = BLOCK %]=pod[% END -%]
[% head1 = BLOCK %]=head1[% END -%]
[% head2 = BLOCK %]=head2[% END -%]
[% head3 = BLOCK %]=head3[% END -%]
[% pod %]
[% head1 %] NAME
[% XSD.create_xsd_name(attribute) %]
[% head1 %] DESCRIPTION
Perl data type class for the XML Schema defined attribute
[% attribute.get_name %] from the namespace [% attribute.get_targetNamespace %].
[% INCLUDE POD/annotation.tt(node = attribute) %]
[% INCLUDE element/POD/contentModel.tt(element = attribute) %]
[% head1 %] METHODS
[% head2 %] new
my $element = [% XSD.create_xsd_name(attribute) %]->new($data);
Constructor. The following data structure may be passed to new():
{ value => $value }
[% head1 %] AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,14 +1,22 @@
package [% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %];
[% USE XSD;
USE Dumper -%]
package [% XSD.create_xsd_name(complexType) %];
use strict;
use warnings;
[% INCLUDE complexType/contentModel.tt %]
[%#
# Don't include any perl source here - there may be sub-packages...
# Don't include any perl source for this package below this line - there
# may be sub-packages...
#-%]
package [% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %]::_ATTR;
use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet);
[% INCLUDE complexType/attributeSet.tt %]
__PACKAGE__->_set_element_form_qualified([%-
IF complexType.schema.get_elementFormDefault == 'qualified'
-%]1[% ELSE %]0[% END %]);
sub get_xmlns { '[% complexType.get_targetNamespace %]' };
[% INCLUDE complexType/contentModel.tt %]
1;
[%# work around for CPAN's indexer, which gets disturbed by pod in templates -%]
@@ -21,21 +29,42 @@ use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet);
[% head1 %] NAME
[% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %]
[% XSD.create_xsd_name(complexType) %]
[% head1 %] DESCRIPTION
Perl data type class for the XML Schema defined complextype
Perl data type class for the XML Schema defined complexType
[% complexType.get_name %] from the namespace [% complexType.get_targetNamespace %].
[% INCLUDE POD/annotation.tt(node = complexType) %]
[% IF (complexType.get_element); %]
[% head2 %] PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=over
[% FOREACH element = complexType.get_element -%]
=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 -%]
[% END %]
=back
[% END -%]
[% head1 %] METHODS
@@ -45,6 +74,8 @@ Constructor. The following data structure may be passed to new():
[% indent = ' '; INCLUDE complexType/POD/structure.tt %]
[% INCLUDE complexType/POD/attributeSet.tt %]
[% head1 %] AUTHOR
Generated by SOAP::WSDL

View File

@@ -1,7 +1,8 @@
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[% 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

@@ -0,0 +1,40 @@
[% head2 = BLOCK %]=head2[% END -%]
[% IF (complexType.get_attribute.size) %]
[% head2 %] attr
NOTE: Attribute documentation is experimental, and may be inaccurate.
See the correspondent WSDL/XML Schema if in question.
This class has additional attributes, accessibly via the C<attr()> method.
attr() returns an object of the class [% XSD.create_xmlattr_name(complexType) %].
The following attributes can be accessed on this object via the corresponding
get_/set_ methods:
=over
[% FOREACH element = complexType.get_attribute;
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) %]
[% element.get_annotation.0.get_documentation %]
[% END; %]
[% IF (type_name=element.get_type);
type = definitions.get_types.0.find_type(element.expand(type_name));
IF (! type);
THROW NOT_FOUND "type " _ type_name _ " for attribute " _ element.get_name _ " not found";
END; %]
This attribute is of type L<[% XSD.create_xsd_name(type) %]|[% XSD.create_xsd_name(type) %]>.
[% END %]
[%- END -%]
=back
[% END %]

View File

@@ -1,9 +1,10 @@
[%USE XSD -%]
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %]
[%- indent = indent _ ' ' %]
[% indent %]# One of the following elements.
[% indent %]# No occurance checks yet, so be sure to pass just one...
[%- 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

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

View File

@@ -1,5 +1,5 @@
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %]
[%- indent = indent _ ' ';
FOREACH element = complexType.get_element %]
[% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%]

View File

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

View File

@@ -0,0 +1 @@
# No documentation generated for simpleContent / extension yet

View File

@@ -0,0 +1,46 @@
{
value => $some_value, # simple perl scalar. See below for restrictions
}
NOTE: This type is derived by restriction as complexType with simpleContent.
Documentation generation for this derivation method is experimental and may
be erroneous/incomplete.
This clase is derived from [%-
IF (name = complexType.get_base);
# type_name = complexType.expand( name );
-%]
[% XSD.create_xsd_name(complexType) %]
[% ELSE;
%] an atomic base type. Unfortunately there's no documentation generated
on atomic base types' base type yet.[%
END -%]
SOAP::WSDL's schema implementation does not validate data yet - however, the
following restrictions apply for this type's value:
[%- FOREACH facet = [
'length',
'minLength',
'maxLength',
'totalDigits',
'fractionDigits',
'minInclusive',
'maxInclusive',
'minExclusive',
'maxExclusive',
'pattern',
'enumeration'
];
IF (facet_method = complexType.can( "get_" _ facet ));
facet_value = facet_method( complexType );
IF (facet_value.size());
%]
[% IF (facet == 'enumeration');
%]valid values (enumeration)
[%- ELSE;
facet;
END -%]:[% FOREACH value = facet_value %] [% value.get_value; END -%]
[% END;
END;
END %]

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