line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyrights 2007-2019 by [Mark Overmeer ]. |
2
|
|
|
|
|
|
|
# For other contributors see ChangeLog. |
3
|
|
|
|
|
|
|
# See the manual pages for details on the licensing terms. |
4
|
|
|
|
|
|
|
# Pod stripped from pm file by OODoc 2.02. |
5
|
|
|
|
|
|
|
# This code is part of distribution XML-Compile-SOAP. Meta-POD processed |
6
|
|
|
|
|
|
|
# with OODoc into POD and HTML manual-pages. See README.md |
7
|
|
|
|
|
|
|
# Copyright Mark Overmeer. Licensed under the same terms as Perl itself. |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package XML::Compile::SOAP; |
10
|
7
|
|
|
7
|
|
1280
|
use vars '$VERSION'; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
380
|
|
11
|
|
|
|
|
|
|
$VERSION = '3.26'; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
14
|
7
|
|
|
7
|
|
39
|
use warnings; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
185
|
|
15
|
7
|
|
|
7
|
|
30
|
use strict; |
|
7
|
|
|
|
|
33
|
|
|
7
|
|
|
|
|
161
|
|
16
|
|
|
|
|
|
|
|
17
|
7
|
|
|
7
|
|
36
|
use Log::Report 'xml-compile-soap'; |
|
7
|
|
|
|
|
27
|
|
|
7
|
|
|
|
|
51
|
|
18
|
|
|
|
|
|
|
|
19
|
7
|
|
|
7
|
|
5160
|
use XML::Compile (); |
|
7
|
|
|
|
|
195352
|
|
|
7
|
|
|
|
|
255
|
|
20
|
7
|
|
|
|
|
474
|
use XML::Compile::Util qw(SCHEMA2001 SCHEMA2001i pack_type |
21
|
7
|
|
|
7
|
|
55
|
unpack_type type_of_node); |
|
7
|
|
|
|
|
14
|
|
22
|
7
|
|
|
7
|
|
3558
|
use XML::Compile::Cache (); |
|
7
|
|
|
|
|
840802
|
|
|
7
|
|
|
|
|
243
|
|
23
|
7
|
|
|
7
|
|
2642
|
use XML::Compile::SOAP::Util qw/:xop10 SOAP11ENC/; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
1023
|
|
24
|
|
|
|
|
|
|
|
25
|
7
|
|
|
7
|
|
4057
|
use Time::HiRes qw/time/; |
|
7
|
|
|
|
|
10892
|
|
|
7
|
|
|
|
|
36
|
|
26
|
7
|
|
|
7
|
|
1187
|
use MIME::Base64 qw/decode_base64/; |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
428
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# XML::Compile::WSA::Util often not installed |
29
|
7
|
|
|
7
|
|
40
|
use constant WSA10 => 'http://www.w3.org/2005/08/addressing'; |
|
7
|
|
|
|
|
9
|
|
|
7
|
|
|
|
|
3786
|
|
30
|
|
|
|
|
|
|
|
31
|
11
|
|
|
11
|
|
58
|
sub _xop_enabled() { exists $INC{'XML/Compile/XOP.pm'} } |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub new($@) |
35
|
6
|
|
|
6
|
1
|
14
|
{ my $class = shift; |
36
|
|
|
|
|
|
|
|
37
|
6
|
50
|
|
|
|
24
|
error __x"you can only instantiate sub-classes of {class}", class => $class |
38
|
|
|
|
|
|
|
if $class eq __PACKAGE__; |
39
|
|
|
|
|
|
|
|
40
|
6
|
|
|
|
|
52
|
(bless {}, $class)->init( {@_} ); |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub init($) |
44
|
6
|
|
|
6
|
0
|
20
|
{ my ($self, $args) = @_; |
45
|
6
|
|
50
|
|
|
131
|
$self->{XCS_mime} = $args->{media_type} || 'application/soap+xml'; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
my $schemas = $self->{XCS_schemas} = $args->{schemas} |
48
|
6
|
|
33
|
|
|
107
|
|| XML::Compile::Cache->new(allow_undeclared => 1 |
49
|
|
|
|
|
|
|
, any_element => 'ATTEMPT', any_attribute => 'ATTEMPT'); |
50
|
|
|
|
|
|
|
|
51
|
6
|
50
|
|
|
|
2685
|
UNIVERSAL::isa($schemas, 'XML::Compile::Cache') |
52
|
|
|
|
|
|
|
or panic "schemas must be a Cache object"; |
53
|
|
|
|
|
|
|
|
54
|
6
|
|
|
|
|
15
|
$self; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub _initSOAP($) |
58
|
6
|
|
|
6
|
|
17
|
{ my ($thing, $schemas) = @_; |
59
|
|
|
|
|
|
|
return $thing |
60
|
6
|
50
|
|
|
|
24
|
if $schemas->{did_init_SOAP}++; # ugly |
61
|
|
|
|
|
|
|
|
62
|
6
|
|
|
|
|
29
|
$schemas->addPrefixes(xsd => SCHEMA2001, xsi => SCHEMA2001i); |
63
|
|
|
|
|
|
|
|
64
|
6
|
|
|
|
|
676
|
$thing; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
{ my (%registered, %envelope); |
69
|
|
|
|
|
|
|
sub register($) |
70
|
7
|
|
|
7
|
1
|
38
|
{ my ($class, $uri, $env, $opclass) = @_; |
71
|
7
|
|
|
|
|
22
|
$registered{$uri} = $class; |
72
|
7
|
50
|
|
|
|
56
|
$envelope{$env} = $opclass if $env; |
73
|
|
|
|
|
|
|
} |
74
|
0
|
|
|
0
|
0
|
0
|
sub plugin($) { $registered{$_[1]} } |
75
|
0
|
|
|
0
|
0
|
0
|
sub fromEnvelope($) { $envelope{$_[1]} } |
76
|
0
|
|
|
0
|
0
|
0
|
sub registered($) { values %registered } |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
#-------------------- |
80
|
|
|
|
|
|
|
|
81
|
0
|
|
|
0
|
1
|
0
|
sub version() {panic "not implemented"} |
82
|
0
|
|
|
0
|
1
|
0
|
sub mediaType() {shift->{XCS_mime}} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub schemas() { |
86
|
7
|
|
|
7
|
|
54
|
use Carp 'cluck'; |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
32024
|
|
87
|
193
|
50
|
|
193
|
1
|
6023
|
ref $_[0] or cluck; |
88
|
193
|
|
|
|
|
720
|
shift->{XCS_schemas}} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
#-------------------- |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub compileMessage($@) |
93
|
11
|
|
|
11
|
1
|
44
|
{ my ($self, $direction, %args) = @_; |
94
|
11
|
|
50
|
|
|
35
|
$args{style} ||= 'document'; |
95
|
|
|
|
|
|
|
|
96
|
11
|
50
|
|
|
|
106
|
$direction eq 'SENDER' ? $self->_sender(%args) |
|
|
100
|
|
|
|
|
|
97
|
|
|
|
|
|
|
: $direction eq 'RECEIVER' ? $self->_receiver(%args) |
98
|
|
|
|
|
|
|
: error __x"message direction is 'SENDER' or 'RECEIVER', not `{dir}'" |
99
|
|
|
|
|
|
|
, dir => $direction; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub messageStructure($) |
104
|
1
|
|
|
1
|
1
|
1697
|
{ my ($thing, $xml) = @_; |
105
|
1
|
50
|
|
|
|
13
|
my $env = $xml->isa('XML::LibXML::Document') ? $xml->documentElement :$xml; |
106
|
|
|
|
|
|
|
|
107
|
1
|
|
|
|
|
3
|
my (@header, @body, $wsa_action); |
108
|
1
|
50
|
|
|
|
5
|
if(my ($header) = $env->getChildrenByLocalName('Header')) |
109
|
1
|
100
|
|
|
|
47
|
{ @header = map { $_->isa('XML::LibXML::Element') ? type_of_node($_) : ()} |
|
3
|
|
|
|
|
48
|
|
110
|
|
|
|
|
|
|
$header->childNodes; |
111
|
|
|
|
|
|
|
|
112
|
1
|
50
|
|
|
|
5
|
if(my $wsa = ($header->getChildrenByTagNameNS(WSA10, 'Action'))[0]) |
113
|
0
|
|
|
|
|
0
|
{ $wsa_action = $wsa->textContent; |
114
|
0
|
|
|
|
|
0
|
for($wsa_action) { s/^\s+//; s/\s+$//; s/\s{2,}/ /g } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
1
|
50
|
|
|
|
30
|
if(my ($body) = $env->getChildrenByLocalName('Body')) |
119
|
1
|
100
|
|
|
|
12
|
{ @body = map { $_->isa('XML::LibXML::Element') ? type_of_node($_) : () } |
|
3
|
|
|
|
|
31
|
|
120
|
|
|
|
|
|
|
$body->childNodes; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
1
|
|
|
|
|
4
|
+{ header => \@header |
124
|
|
|
|
|
|
|
, body => \@body |
125
|
|
|
|
|
|
|
, wsa_action => $wsa_action |
126
|
|
|
|
|
|
|
}; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
#------------------------------------------------ |
130
|
|
|
|
|
|
|
# Sender |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub _sender(@) |
133
|
5
|
|
|
5
|
|
30
|
{ my ($self, %args) = @_; |
134
|
|
|
|
|
|
|
|
135
|
5
|
50
|
|
|
|
21
|
error __"option 'role' only for readers" if $args{role}; |
136
|
5
|
50
|
|
|
|
20
|
error __"option 'roles' only for readers" if $args{roles}; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
my $hooks = $args{hooks} # make copy of calling hook-list |
139
|
5
|
50
|
|
|
|
21
|
= $args{hooks} ? [ @{$args{hooks}} ] : []; |
|
0
|
|
|
|
|
0
|
|
140
|
|
|
|
|
|
|
|
141
|
5
|
|
|
|
|
11
|
my @mtom; |
142
|
5
|
100
|
|
|
|
28
|
push @$hooks, $self->_writer_xop_hook(\@mtom) |
143
|
|
|
|
|
|
|
if _xop_enabled; |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
my ($body, $blabels) = $args{create_body} |
146
|
5
|
50
|
|
|
|
73
|
? $args{create_body}->($self, %args) |
147
|
|
|
|
|
|
|
: $self->_writer_body(\%args); |
148
|
5
|
|
|
|
|
47
|
my ($faults, $flabels) = $self->_writer_faults(\%args, $args{faults}); |
149
|
|
|
|
|
|
|
|
150
|
5
|
|
|
|
|
54
|
my ($header, $hlabels) = $self->_writer_header(\%args); |
151
|
5
|
|
|
|
|
37
|
push @$hooks, $self->_writer_hook($self->envType('Header'), @$header); |
152
|
|
|
|
|
|
|
|
153
|
5
|
|
50
|
|
|
25
|
my $style = $args{style} || 'none'; |
154
|
5
|
50
|
|
|
|
21
|
if($style eq 'document') |
|
|
0
|
|
|
|
|
|
155
|
5
|
|
|
|
|
28
|
{ push @$hooks, $self->_writer_hook($self->envType('Body') |
156
|
|
|
|
|
|
|
, @$body, @$faults); |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
elsif($style eq 'rpc') |
159
|
|
|
|
|
|
|
{ my $procedure = $args{procedure} || $args{body}{procedure} |
160
|
0
|
0
|
0
|
|
|
0
|
or error __x"sending operation requires procedure name with RPC"; |
161
|
|
|
|
|
|
|
|
162
|
0
|
|
0
|
|
|
0
|
my $use = $args{use} || $args{body}{use} || 'literal'; |
163
|
0
|
|
|
|
|
0
|
my $bt = $self->envType('Body'); |
164
|
0
|
0
|
|
|
|
0
|
push @$hooks, $use eq 'literal' |
165
|
|
|
|
|
|
|
? $self->_writer_body_rpclit_hook($bt, $procedure, $body, $faults) |
166
|
|
|
|
|
|
|
: $self->_writer_body_rpcenc_hook($bt, $procedure, $body, $faults); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
else |
169
|
0
|
|
|
|
|
0
|
{ error __x"unknown style `{style}'", style => $style; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# |
173
|
|
|
|
|
|
|
# Pack everything together in one procedure |
174
|
|
|
|
|
|
|
# |
175
|
|
|
|
|
|
|
|
176
|
5
|
|
|
|
|
20
|
my $envelope = $self->_writer($self->envType('Envelope'), %args); |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub |
179
|
10
|
100
|
|
10
|
|
9104
|
{ my ($values, $charset) = ref $_[0] eq 'HASH' ? @_ : ( {@_}, undef); |
180
|
10
|
|
|
|
|
46
|
my %copy = %$values; # do not destroy the calling hash |
181
|
|
|
|
|
|
|
my $doc = delete $copy{_doc} |
182
|
10
|
|
33
|
|
|
413
|
|| XML::LibXML::Document->new('1.0', $charset || 'UTF-8'); |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
my %data = ( |
185
|
|
|
|
|
|
|
Body => delete $copy{Body} || {}, |
186
|
|
|
|
|
|
|
Header => delete $copy{Header}, |
187
|
10
|
|
50
|
|
|
114
|
); |
188
|
|
|
|
|
|
|
|
189
|
10
|
|
|
|
|
37
|
foreach my $label (@$hlabels) |
190
|
4
|
100
|
|
|
|
11
|
{ exists $copy{$label} or next; |
191
|
3
|
|
33
|
|
|
18
|
$data{Header}{$label} ||= delete $copy{$label}; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
10
|
|
|
|
|
32
|
foreach my $label (@$blabels, @$flabels) |
195
|
20
|
100
|
|
|
|
56
|
{ exists $copy{$label} or next; |
196
|
8
|
|
33
|
|
|
54
|
$data{Body}{$label} ||= delete $copy{$label}; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
10
|
50
|
66
|
|
|
43
|
if(@$blabels==2 && !keys %{$data{Body}} ) # ignore 'Fault' |
|
7
|
50
|
|
|
|
61
|
|
200
|
|
|
|
|
|
|
{ # even when no params, we fill at least one body element |
201
|
0
|
|
|
|
|
0
|
$data{Body}{$blabels->[0]} = \%copy; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
elsif(keys %copy) |
204
|
0
|
|
|
|
|
0
|
{ trace __x"available blocks: {blocks}", |
205
|
|
|
|
|
|
|
blocks => [ sort @$hlabels, @$blabels, @$flabels ]; |
206
|
0
|
|
|
|
|
0
|
error __x"call data not used: {blocks}", blocks => [keys %copy]; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
10
|
|
|
|
|
26
|
@mtom = (); # filled via hook |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
#use Data::Dumper; |
212
|
|
|
|
|
|
|
#warn "REPROCESSED: ", Dumper \%data; |
213
|
10
|
50
|
|
|
|
39
|
my $root = $envelope->($doc, \%data) |
214
|
|
|
|
|
|
|
or return; |
215
|
|
|
|
|
|
|
|
216
|
10
|
|
|
|
|
1343
|
$doc->setDocumentElement($root); |
217
|
|
|
|
|
|
|
|
218
|
10
|
100
|
|
|
|
135
|
return ($doc, \@mtom) |
219
|
|
|
|
|
|
|
if wantarray; |
220
|
|
|
|
|
|
|
|
221
|
8
|
50
|
|
|
|
35
|
@mtom == 0 |
222
|
|
|
|
|
|
|
or error __x"{nr} XOP objects lost in sender" |
223
|
|
|
|
|
|
|
, nr => scalar @mtom; |
224
|
8
|
|
|
|
|
37
|
$doc; |
225
|
5
|
|
|
|
|
30094
|
}; |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub _writer_hook($$@) |
229
|
10
|
|
|
10
|
|
95
|
{ my ($self, $type, @do) = @_; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
my $code = sub |
232
|
13
|
|
|
13
|
|
816
|
{ my ($doc, $data, $path, $tag) = @_; |
233
|
13
|
50
|
|
|
|
48
|
UNIVERSAL::isa($data, 'XML::LibXML::Element') |
234
|
|
|
|
|
|
|
and return $data; |
235
|
|
|
|
|
|
|
|
236
|
13
|
|
|
|
|
48
|
my %data = %$data; |
237
|
13
|
|
|
|
|
35
|
my @h = @do; |
238
|
13
|
|
|
|
|
18
|
my @childs; |
239
|
13
|
|
|
|
|
36
|
while(@h) |
240
|
23
|
|
|
|
|
1002
|
{ my ($k, $c) = (shift @h, shift @h); |
241
|
23
|
100
|
|
|
|
74
|
if(my $v = delete $data{$k}) |
242
|
11
|
|
|
|
|
37
|
{ push @childs, $c->($doc, $v); |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
13
|
50
|
|
|
|
873
|
if(keys %data) |
247
|
0
|
|
|
|
|
0
|
{ warning __x"unused values {names}", names => [keys %data]; |
248
|
0
|
|
|
|
|
0
|
my @h = @do; my @keys; |
|
0
|
|
|
|
|
0
|
|
249
|
0
|
|
|
|
|
0
|
while(@h) { push @keys, shift @h; shift @h} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
250
|
0
|
|
|
|
|
0
|
trace "expected: ". join ' ', @keys; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
13
|
|
|
|
|
67
|
my $node = $doc->createElement($tag); |
254
|
13
|
|
|
|
|
113
|
$node->appendChild($_) for @childs; |
255
|
13
|
|
|
|
|
211
|
$node; |
256
|
10
|
|
|
|
|
73
|
}; |
257
|
|
|
|
|
|
|
|
258
|
10
|
|
|
|
|
80
|
+{ type => $type, replace => $code }; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub _writer_body_rpclit_hook($$$$$) |
262
|
0
|
|
|
0
|
|
0
|
{ my ($self, $type, $procedure, $params, $faults) = @_; |
263
|
0
|
|
|
|
|
0
|
my @params = @$params; |
264
|
0
|
|
|
|
|
0
|
my @faults = @$faults; |
265
|
0
|
|
|
|
|
0
|
my $schemas = $self->schemas; |
266
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
0
|
my $proc = $schemas->prefixed($procedure); |
268
|
0
|
|
|
|
|
0
|
my ($prefix) = split /\:/, $proc; |
269
|
0
|
|
|
|
|
0
|
my $prefdef = $schemas->prefix($prefix); |
270
|
0
|
|
|
|
|
0
|
my $proc_ns = $prefdef->{uri}; |
271
|
0
|
|
|
|
|
0
|
$prefdef->{used} = 0; |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
my $code = sub |
274
|
0
|
|
|
0
|
|
0
|
{ my ($doc, $data, $path, $tag) = @_; |
275
|
0
|
0
|
|
|
|
0
|
UNIVERSAL::isa($data, 'XML::LibXML::Element') |
276
|
|
|
|
|
|
|
and return $data; |
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
|
|
0
|
my %data = %$data; |
279
|
0
|
|
|
|
|
0
|
my @f = @faults; |
280
|
0
|
|
|
|
|
0
|
my (@fchilds, @pchilds); |
281
|
0
|
|
|
|
|
0
|
while(@f) |
282
|
0
|
|
|
|
|
0
|
{ my ($k, $c) = (shift @f, shift @f); |
283
|
0
|
|
|
|
|
0
|
my $v = delete $data{$k}; |
284
|
0
|
0
|
|
|
|
0
|
push @fchilds, $c->($doc, $v) if defined $v; |
285
|
|
|
|
|
|
|
} |
286
|
0
|
|
|
|
|
0
|
my @p = @params; |
287
|
0
|
|
|
|
|
0
|
while(@p) |
288
|
0
|
|
|
|
|
0
|
{ my ($k, $c) = (shift @p, shift @p); |
289
|
0
|
|
|
|
|
0
|
my $v = delete $data{$k}; |
290
|
0
|
0
|
|
|
|
0
|
push @pchilds, $c->($doc, $v) if defined $v; |
291
|
|
|
|
|
|
|
} |
292
|
0
|
0
|
|
|
|
0
|
warning __x"unused values {names}", names => [keys %data] |
293
|
|
|
|
|
|
|
if keys %data; |
294
|
|
|
|
|
|
|
|
295
|
0
|
|
|
|
|
0
|
my $proc = $doc->createElement($proc); |
296
|
0
|
|
|
|
|
0
|
$proc->setNamespace($proc_ns, $prefix, 0); |
297
|
0
|
|
|
|
|
0
|
$proc->setAttribute("SOAP-ENV:encodingStyle", SOAP11ENC); |
298
|
|
|
|
|
|
|
|
299
|
0
|
|
|
|
|
0
|
$proc->appendChild($_) for @pchilds; |
300
|
|
|
|
|
|
|
|
301
|
0
|
|
|
|
|
0
|
my $node = $doc->createElement($tag); |
302
|
0
|
|
|
|
|
0
|
$node->appendChild($proc); |
303
|
0
|
|
|
|
|
0
|
$node->appendChild($_) for @fchilds; |
304
|
0
|
|
|
|
|
0
|
$node; |
305
|
0
|
|
|
|
|
0
|
}; |
306
|
|
|
|
|
|
|
|
307
|
0
|
|
|
|
|
0
|
+{ type => $type, replace => $code }; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
*_writer_body_rpcenc_hook = \&_writer_body_rpclit_hook; |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub _writer_header($) |
313
|
5
|
|
|
5
|
|
17
|
{ my ($self, $args) = @_; |
314
|
5
|
|
|
|
|
52
|
my (@rules, @hlabels); |
315
|
|
|
|
|
|
|
|
316
|
5
|
|
100
|
|
|
34
|
my $header = $args->{header} || []; |
317
|
5
|
|
|
|
|
21
|
my $soapenv = $self->envelopeNS; |
318
|
|
|
|
|
|
|
|
319
|
5
|
50
|
|
|
|
114
|
foreach my $h (ref $header eq 'ARRAY' ? @$header : $header) |
320
|
2
|
|
|
|
|
8
|
{ my $part = $h->{parts}[0]; |
321
|
2
|
|
|
|
|
6
|
my $label = $part->{name}; |
322
|
2
|
|
|
|
|
5
|
my $code = $part->{writer}; |
323
|
2
|
50
|
|
|
|
8
|
if($part->{element}) |
|
|
0
|
|
|
|
|
|
324
|
2
|
|
33
|
|
|
69
|
{ $code ||= $self->_writer_part_element($args, $part); |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
elsif(my $type = $part->{type}) |
327
|
0
|
|
0
|
|
|
0
|
{ $code ||= $self->_writer_part_type($args, $part); |
328
|
0
|
|
|
|
|
0
|
$label = (unpack_type $part->{name})[1]; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
else |
331
|
0
|
|
|
|
|
0
|
{ error __x"header part {name} has neither `element' nor `type'" |
332
|
|
|
|
|
|
|
, name => $label; |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
2
|
|
|
|
|
55
|
push @rules, $label => $code; |
336
|
2
|
|
|
|
|
7
|
push @hlabels, $label; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
|
339
|
5
|
|
|
|
|
23
|
(\@rules, \@hlabels); |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub _writer_body($) |
343
|
5
|
|
|
5
|
|
17
|
{ my ($self, $args) = @_; |
344
|
5
|
|
|
|
|
22
|
my (@rules, @blabels); |
345
|
|
|
|
|
|
|
|
346
|
5
|
|
33
|
|
|
22
|
my $body = $args->{body} || $args->{fault}; |
347
|
5
|
|
100
|
|
|
24
|
my $use = $body->{use} || 'literal'; |
348
|
|
|
|
|
|
|
# $use eq 'literal' |
349
|
|
|
|
|
|
|
# or error __x"RPC encoded not supported by this version"; |
350
|
|
|
|
|
|
|
|
351
|
5
|
|
50
|
|
|
18
|
my $parts = $body->{parts} || []; |
352
|
5
|
|
|
|
|
9
|
my $style = $args->{style}; |
353
|
5
|
|
33
|
|
|
35
|
local $args->{is_rpc_enc} = $style eq 'rpc' && $use eq 'encoded'; |
354
|
|
|
|
|
|
|
|
355
|
5
|
|
|
|
|
17
|
foreach my $part (@$parts) |
356
|
9
|
|
|
|
|
21
|
{ my $label = $part->{name}; |
357
|
9
|
|
|
|
|
12
|
my $code; |
358
|
9
|
50
|
|
|
|
24
|
if($part->{element}) |
|
|
0
|
|
|
|
|
|
359
|
9
|
|
|
|
|
44
|
{ $code = $self->_writer_part_element($args, $part); |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
elsif(my $type = $part->{type}) |
362
|
0
|
|
|
|
|
0
|
{ $code = $self->_writer_part_type($args, $part); |
363
|
0
|
|
|
|
|
0
|
$label = (unpack_type $part->{name})[1]; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
else |
366
|
0
|
|
|
|
|
0
|
{ error __x"body part {name} has neither `element' nor `type'" |
367
|
|
|
|
|
|
|
, name => $label; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
9
|
|
|
|
|
122
|
push @rules, $label => $code; |
371
|
9
|
|
|
|
|
22
|
push @blabels, $label; |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
|
374
|
5
|
|
|
|
|
27
|
(\@rules, \@blabels); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
sub _writer_part_element($$) |
378
|
11
|
|
|
11
|
|
29
|
{ my ($self, $args, $part) = @_; |
379
|
11
|
|
|
|
|
24
|
my $element = $part->{element}; |
380
|
11
|
|
|
|
|
58
|
my $soapenv = $self->envelopeNS; |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
$part->{writer} ||= $self->_writer |
383
|
|
|
|
|
|
|
( $element, %$args |
384
|
30
|
100
|
|
30
|
|
11518
|
, include_namespaces => sub {$_[0] ne $soapenv && $_[2]} |
385
|
|
|
|
|
|
|
, xsi_type_everywhere => $args->{is_rpc_enc} |
386
|
11
|
|
66
|
|
|
114
|
); |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub _writer_part_type($$) |
390
|
0
|
|
|
0
|
|
0
|
{ my ($self, $args, $part) = @_; |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
$args->{style} eq 'rpc' |
393
|
|
|
|
|
|
|
or error __x"part {name} uses `type', only for rpc not {style}" |
394
|
0
|
0
|
|
|
|
0
|
, name => $part->{name}, style => $args->{style}; |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
return $part->{writer} |
397
|
0
|
0
|
|
|
|
0
|
if $part->{writer}; |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
|
|
0
|
my $soapenv = $self->envelopeNS; |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
$part->{writer} = $self->schemas->compileType |
402
|
|
|
|
|
|
|
( WRITER => $part->{type}, %$args, element => $part->{name} |
403
|
0
|
0
|
|
0
|
|
0
|
, include_namespaces => sub {$_[0] ne $soapenv && $_[2]} |
404
|
|
|
|
|
|
|
, xsi_type_everywhere => $args->{is_rpc_enc} |
405
|
0
|
|
|
|
|
0
|
); |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
0
|
|
|
0
|
|
0
|
sub _writer_faults($) { ([], []) } |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub _writer_xop_hook($) |
411
|
1
|
|
|
1
|
|
3
|
{ my ($self, $xop_objects) = @_; |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
my $collect_objects = sub { |
414
|
4
|
|
|
4
|
|
252
|
my ($doc, $val, $path, $tag, $r) = @_; |
415
|
4
|
100
|
|
|
|
27
|
return $r->($doc, $val) |
416
|
|
|
|
|
|
|
unless UNIVERSAL::isa($val, 'XML::Compile::XOP::Include'); |
417
|
|
|
|
|
|
|
|
418
|
1
|
|
|
|
|
7
|
my $node = $val->xmlNode($doc, $path, $tag); |
419
|
1
|
|
|
|
|
14
|
push @$xop_objects, $val; |
420
|
1
|
|
|
|
|
51
|
$node; |
421
|
1
|
|
|
|
|
5
|
}; |
422
|
|
|
|
|
|
|
|
423
|
1
|
|
|
|
|
5
|
+{ extends => 'xsd:base64Binary', replace => $collect_objects }; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
#------------------------------------------------ |
427
|
|
|
|
|
|
|
# Receiver |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub _receiver(@) |
430
|
6
|
|
|
6
|
|
23
|
{ my ($self, %args) = @_; |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
error __"option 'destination' only for writers" |
433
|
6
|
50
|
|
|
|
27
|
if $args{destination}; |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
error __"option 'mustUnderstand' only for writers" |
436
|
6
|
50
|
|
|
|
22
|
if $args{understand}; |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
# roles are not checked (yet) |
439
|
|
|
|
|
|
|
# my $roles = $args{roles} || $args{role} || 'ULTIMATE'; |
440
|
|
|
|
|
|
|
# my @roles = ref $roles eq 'ARRAY' ? @$roles : $roles; |
441
|
|
|
|
|
|
|
|
442
|
6
|
|
|
|
|
56
|
my $header = $self->_reader_header(\%args); |
443
|
|
|
|
|
|
|
|
444
|
6
|
|
|
|
|
13
|
my $xops; # forward backwards pass-on |
445
|
6
|
|
|
|
|
54
|
my $body = $self->_reader_body(\%args, \$xops); |
446
|
|
|
|
|
|
|
|
447
|
6
|
|
50
|
|
|
28
|
my $style = $args{style} || 'document'; |
448
|
6
|
|
50
|
|
|
39
|
my $kind = $args{kind} || 'request-response'; |
449
|
6
|
50
|
|
|
|
34
|
if($style eq 'rpc') |
|
|
50
|
|
|
|
|
|
450
|
0
|
|
0
|
|
|
0
|
{ my $procedure = $args{procedure} || $args{body}{procedure}; |
451
|
0
|
0
|
0
|
|
|
0
|
keys %{$args{body}}==0 || $procedure |
|
0
|
|
|
|
|
0
|
|
452
|
|
|
|
|
|
|
or error __x"receiving operation requires procedure name with RPC"; |
453
|
|
|
|
|
|
|
|
454
|
0
|
|
0
|
|
|
0
|
my $use = $args{use} || $args{body}{use} || 'literal'; |
455
|
0
|
0
|
|
|
|
0
|
$body = $use eq 'literal' |
456
|
|
|
|
|
|
|
? $self->_reader_body_rpclit_wrapper($procedure, $body) |
457
|
|
|
|
|
|
|
: $self->_reader_body_rpcenc_wrapper($procedure, $body); |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
elsif($style ne 'document') |
460
|
0
|
|
|
|
|
0
|
{ error __x"unknown style `{style}'", style => $style; |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# faults are always possible |
464
|
6
|
|
|
|
|
83
|
push @$body, $self->_reader_fault_reader; |
465
|
|
|
|
|
|
|
|
466
|
6
|
50
|
|
|
|
31336
|
my @hooks = @{$self->{hooks} || []}; |
|
6
|
|
|
|
|
60
|
|
467
|
6
|
|
|
|
|
36
|
push @hooks |
468
|
|
|
|
|
|
|
, $self->_reader_hook($self->envType('Header'), $header) |
469
|
|
|
|
|
|
|
, $self->_reader_hook($self->envType('Body'), $body ); |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# |
472
|
|
|
|
|
|
|
# Pack everything together in one procedure |
473
|
|
|
|
|
|
|
# |
474
|
|
|
|
|
|
|
|
475
|
6
|
|
|
|
|
28
|
my $envelope = $self->_reader($self->envType('Envelope') |
476
|
|
|
|
|
|
|
, %args, hooks => \@hooks); |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
# add simplified fault information |
479
|
6
|
|
|
|
|
32643
|
my $faultdec = $self->_reader_faults(\%args, $args{faults}); |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
sub |
482
|
9
|
|
|
9
|
|
7529
|
{ (my $xml, $xops) = @_; |
483
|
9
|
|
|
|
|
37
|
my $data = $envelope->($xml); |
484
|
9
|
100
|
|
|
|
61
|
my @pairs = ( %{delete $data->{Header} || {}} |
485
|
9
|
50
|
|
|
|
1097
|
, %{delete $data->{Body} || {}}); |
|
9
|
|
|
|
|
57
|
|
486
|
9
|
|
|
|
|
39
|
while(@pairs) |
487
|
10
|
|
|
|
|
30
|
{ my $k = shift @pairs; |
488
|
10
|
|
|
|
|
32
|
$data->{$k} = shift @pairs; |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
|
491
|
9
|
|
|
|
|
38
|
$faultdec->($data); |
492
|
9
|
|
|
|
|
55
|
$data; |
493
|
6
|
|
|
|
|
104
|
}; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
sub _reader_hook($$) |
497
|
12
|
|
|
12
|
|
132
|
{ my ($self, $type, $do) = @_; |
498
|
12
|
|
|
|
|
69
|
my %trans = map +($_->[1] => [ $_->[0], $_->[2] ]), @$do; # we need copies |
499
|
12
|
|
|
|
|
40
|
my $envns = $self->envelopeNS; |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
my $code = sub |
502
|
12
|
|
|
12
|
|
4962
|
{ my ($xml, $trans, $path, $label) = @_; |
503
|
12
|
|
|
|
|
25
|
my %h; |
504
|
12
|
|
|
|
|
34
|
foreach my $child ($xml->childNodes) |
505
|
23
|
100
|
|
|
|
173
|
{ next unless $child->isa('XML::LibXML::Element'); |
506
|
10
|
|
|
|
|
38
|
my $type = type_of_node $child; |
507
|
10
|
100
|
|
|
|
203
|
if(my $t = $trans{$type}) |
508
|
9
|
|
|
|
|
28
|
{ my ($label, $code) = @$t; |
509
|
9
|
50
|
|
|
|
30
|
my $v = $code->($child) or next; |
510
|
9
|
50
|
|
|
|
1923
|
if(!defined $v) { } |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
511
|
9
|
|
|
|
|
29
|
elsif(!exists $h{$label}) { $h{$label} = $v } |
512
|
0
|
|
|
|
|
0
|
elsif(ref $h{$label} eq 'ARRAY') { push @{$h{$label}}, $v } |
|
0
|
|
|
|
|
0
|
|
513
|
0
|
|
|
|
|
0
|
else { $h{$label} = [ $h{$label}, $v ] } |
514
|
9
|
|
|
|
|
28
|
next; |
515
|
|
|
|
|
|
|
} |
516
|
|
|
|
|
|
|
else |
517
|
1
|
|
|
|
|
4
|
{ $h{$type} = $child; |
518
|
1
|
|
|
|
|
7
|
trace __x"node {type} not understood, expected are {has}", |
519
|
|
|
|
|
|
|
type => $type, has => [sort keys %trans]; |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
|
522
|
1
|
50
|
50
|
|
|
100
|
return ($label => $self->replyMustUnderstandFault($type)) |
523
|
|
|
|
|
|
|
if $child->getAttributeNS($envns, 'mustUnderstand') || 0; |
524
|
|
|
|
|
|
|
} |
525
|
11
|
|
|
|
|
57
|
($label => \%h); |
526
|
12
|
|
|
|
|
53
|
}; |
527
|
|
|
|
|
|
|
|
528
|
12
|
|
|
|
|
57
|
+{ type => $type |
529
|
|
|
|
|
|
|
, replace => $code |
530
|
|
|
|
|
|
|
}; |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
} |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
sub _reader_body_rpclit_wrapper($$) |
535
|
0
|
|
|
0
|
|
0
|
{ my ($self, $procedure, $body) = @_; |
536
|
0
|
|
|
|
|
0
|
my %trans = map +($_->[1] => [ $_->[0], $_->[2] ]), @$body; |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# this should use key_rewrite, but there is no $wsdl here |
539
|
|
|
|
|
|
|
# my $label = $wsdl->prefixed($procedure); |
540
|
0
|
|
|
|
|
0
|
my $label = (unpack_type $procedure)[1]; |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
my $code = sub |
543
|
0
|
0
|
|
0
|
|
0
|
{ my $xml = shift or return {}; |
544
|
0
|
|
|
|
|
0
|
my %h; |
545
|
0
|
|
|
|
|
0
|
foreach my $child ($xml->childNodes) |
546
|
0
|
0
|
|
|
|
0
|
{ $child->isa('XML::LibXML::Element') or next; |
547
|
0
|
|
|
|
|
0
|
my $type = type_of_node $child; |
548
|
0
|
0
|
|
|
|
0
|
if(my $t = $trans{$type}) |
549
|
0
|
|
|
|
|
0
|
{ $h{$t->[0]} = $t->[1]->($child) } |
550
|
0
|
|
|
|
|
0
|
else { $h{$type} = $child } |
551
|
|
|
|
|
|
|
} |
552
|
0
|
|
|
|
|
0
|
\%h; |
553
|
0
|
|
|
|
|
0
|
}; |
554
|
|
|
|
|
|
|
|
555
|
0
|
|
|
|
|
0
|
[ [ $label => $procedure => $code ] ]; |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
sub _reader_header($) |
559
|
6
|
|
|
6
|
|
21
|
{ my ($self, $args) = @_; |
560
|
6
|
|
100
|
|
|
64
|
my $header = $args->{header} || []; |
561
|
6
|
|
|
|
|
14
|
my @rules; |
562
|
|
|
|
|
|
|
|
563
|
6
|
|
|
|
|
19
|
foreach my $h (@$header) |
564
|
2
|
|
|
|
|
5
|
{ my $part = $h->{parts}[0]; |
565
|
2
|
|
|
|
|
4
|
my $label = $part->{name}; |
566
|
2
|
|
|
|
|
5
|
my $element = $part->{element}; |
567
|
2
|
|
33
|
|
|
27
|
my $code = $part->{reader} ||= $self->_reader($element, %$args); |
568
|
2
|
|
|
|
|
28798
|
push @rules, [$label, $element, $code]; |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
|
571
|
6
|
|
|
|
|
18
|
\@rules; |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
sub _reader_body($$) |
575
|
6
|
|
|
6
|
|
16
|
{ my ($self, $args, $refxops) = @_; |
576
|
6
|
|
|
|
|
14
|
my $body = $args->{body}; |
577
|
6
|
|
100
|
|
|
45
|
my $parts = $body->{parts} || []; |
578
|
6
|
50
|
|
|
|
14
|
my @hooks = @{$args->{hooks} || []}; |
|
6
|
|
|
|
|
32
|
|
579
|
6
|
100
|
|
|
|
21
|
push @hooks, $self->_reader_xop_hook($refxops) |
580
|
|
|
|
|
|
|
if _xop_enabled; |
581
|
|
|
|
|
|
|
|
582
|
6
|
|
|
|
|
24
|
local $args->{hooks} = \@hooks; |
583
|
|
|
|
|
|
|
|
584
|
6
|
|
|
|
|
10
|
my @rules; |
585
|
6
|
|
|
|
|
18
|
foreach my $part (@$parts) |
586
|
4
|
|
|
|
|
9
|
{ my $label = $part->{name}; |
587
|
|
|
|
|
|
|
|
588
|
4
|
|
|
|
|
8
|
my ($t, $code); |
589
|
4
|
50
|
|
|
|
16
|
if($part->{element}) |
|
|
0
|
|
|
|
|
|
590
|
4
|
|
|
|
|
28
|
{ ($t, $code) = $self->_reader_body_element($args, $part) } |
591
|
|
|
|
|
|
|
elsif($part->{type}) |
592
|
0
|
|
|
|
|
0
|
{ ($t, $code) = $self->_reader_body_type($args, $part) } |
593
|
|
|
|
|
|
|
else |
594
|
0
|
|
|
|
|
0
|
{ error __x"part {name} has neither element nor type specified" |
595
|
|
|
|
|
|
|
, name => $label; |
596
|
|
|
|
|
|
|
} |
597
|
4
|
|
|
|
|
42
|
push @rules, [ $label, $t, $code ]; |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
#use Data::Dumper; |
601
|
|
|
|
|
|
|
#warn "RULES=", Dumper \@rules, $parts; |
602
|
6
|
|
|
|
|
23
|
\@rules; |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
sub _reader_body_element($$) |
606
|
4
|
|
|
4
|
|
11
|
{ my ($self, $args, $part) = @_; |
607
|
|
|
|
|
|
|
|
608
|
4
|
|
|
|
|
9
|
my $element = $part->{element}; |
609
|
4
|
|
33
|
|
|
51
|
my $code = $part->{reader} || $self->_reader($element, %$args); |
610
|
|
|
|
|
|
|
|
611
|
4
|
|
|
|
|
44308
|
($element, $code); |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub _reader_body_type($$) |
615
|
0
|
|
|
0
|
|
0
|
{ my ($self, $args, $part) = @_; |
616
|
0
|
|
|
|
|
0
|
my $name = $part->{name}; |
617
|
|
|
|
|
|
|
|
618
|
0
|
0
|
|
|
|
0
|
$args->{style} eq 'rpc' |
619
|
|
|
|
|
|
|
or error __x"only rpc style messages can use 'type' as used by {part}" |
620
|
|
|
|
|
|
|
, part => $name; |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
return $part->{reader} |
623
|
0
|
0
|
|
|
|
0
|
if $part->{reader}; |
624
|
|
|
|
|
|
|
|
625
|
0
|
|
|
|
|
0
|
my $type = $part->{type}; |
626
|
0
|
|
|
|
|
0
|
my ($ns, $local) = unpack_type $type; |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
my $r = $part->{reader} = |
629
|
0
|
|
|
|
|
0
|
$self->schemas->compileType |
630
|
|
|
|
|
|
|
( READER => $type, %$args |
631
|
|
|
|
|
|
|
, element => $name # $args->{body}{procedure} |
632
|
|
|
|
|
|
|
); |
633
|
|
|
|
|
|
|
|
634
|
0
|
|
|
|
|
0
|
($name, $r); |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub _reader_faults($) |
638
|
0
|
|
|
0
|
|
0
|
{ my ($self, $args) = @_; |
639
|
0
|
|
|
0
|
|
0
|
sub { shift }; |
|
0
|
|
|
|
|
0
|
|
640
|
|
|
|
|
|
|
} |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
sub _reader_xop_hook($) |
643
|
1
|
|
|
1
|
|
2
|
{ my ($self, $refxops) = @_; |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
my $xop_merge = sub |
646
|
4
|
|
|
4
|
|
900
|
{ my ($xml, $args, $path, $type, $r) = @_; |
647
|
4
|
100
|
|
|
|
15
|
if(my $incls = $xml->getElementsByTagNameNS(XOP10, 'Include')) |
648
|
1
|
50
|
50
|
|
|
176
|
{ my $href = $incls->shift->getAttribute('href') || '' |
649
|
|
|
|
|
|
|
or return ($type => $xml); |
650
|
|
|
|
|
|
|
|
651
|
1
|
|
|
|
|
38
|
$href =~ s/^cid://; |
652
|
1
|
50
|
|
|
|
32
|
my $xop = $$refxops->{$href} |
653
|
|
|
|
|
|
|
or return ($type => $xml); |
654
|
|
|
|
|
|
|
|
655
|
1
|
|
|
|
|
8
|
return ($type => $xop); |
656
|
|
|
|
|
|
|
} |
657
|
|
|
|
|
|
|
|
658
|
3
|
|
|
|
|
491
|
($type => decode_base64 $xml->textContent); |
659
|
1
|
|
|
|
|
6
|
}; |
660
|
|
|
|
|
|
|
|
661
|
1
|
|
|
|
|
17
|
+{ type => 'xsd:base64Binary', replace => $xop_merge }; |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
|
664
|
12
|
|
|
12
|
|
78
|
sub _reader(@) { shift->schemas->reader(@_) } |
665
|
17
|
|
|
17
|
|
90
|
sub _writer(@) { shift->schemas->writer(@_) } |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
#------------------------------------------------ |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
|
670
|
0
|
|
|
0
|
1
|
|
sub roleURI($) { panic "not implemented" } |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
|
673
|
0
|
|
|
0
|
1
|
|
sub roleAbbreviation($) { panic "not implemented" } |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
|
676
|
0
|
|
|
0
|
1
|
|
sub replyMustUnderstandFault($) { panic "not implemented" } |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
#---------------------- |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
1; |