line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# ====================================================================== |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (C) 2000-2005 Paul Kulchenko (paulclinger@yahoo.com) |
4
|
|
|
|
|
|
|
# SOAP::Lite is free software; you can redistribute it |
5
|
|
|
|
|
|
|
# and/or modify it under the same terms as Perl itself. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# ====================================================================== |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# Formatting hint: |
10
|
|
|
|
|
|
|
# Target is the source code format laid out in Perl Best Practices (4 spaces |
11
|
|
|
|
|
|
|
# indent, opening brace on condition line, no cuddled else). |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# October 2007, Martin Kutter |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
package SOAP::Lite; |
16
|
|
|
|
|
|
|
|
17
|
25
|
|
|
25
|
|
128628
|
use strict; |
|
25
|
|
|
|
|
43
|
|
|
25
|
|
|
|
|
1043
|
|
18
|
25
|
|
|
25
|
|
118
|
use warnings; |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
6077
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our $VERSION = '1.13'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
package SOAP::XMLSchemaApacheSOAP::Deserializer; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub as_map { |
25
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
26
|
|
|
|
|
|
|
return { |
27
|
0
|
|
|
|
|
0
|
map { |
28
|
0
|
0
|
|
|
|
0
|
my $hash = ($self->decode_object($_))[1]; |
29
|
0
|
|
|
|
|
0
|
($hash->{key} => $hash->{value}) |
30
|
0
|
|
|
|
|
0
|
} @{$_[3] || []} |
31
|
|
|
|
|
|
|
}; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
sub as_Map; *as_Map = \&as_map; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Thank to Kenneth Draper for this contribution |
36
|
|
|
|
|
|
|
sub as_vector { |
37
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
38
|
0
|
0
|
|
|
|
0
|
return [ map { scalar(($self->decode_object($_))[1]) } @{$_[3] || []} ]; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
sub as_Vector; *as_Vector = \&as_vector; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
package SOAP::XMLSchema::Serializer; |
45
|
|
|
|
|
|
|
|
46
|
25
|
|
|
25
|
|
140
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
41
|
|
|
25
|
|
|
|
|
2954
|
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub xmlschemaclass { |
49
|
136
|
|
|
136
|
|
176
|
my $self = shift; |
50
|
136
|
100
|
|
|
|
520
|
return $ISA[0] unless @_; |
51
|
25
|
|
|
|
|
609
|
@ISA = (shift); |
52
|
25
|
|
|
|
|
102
|
return $self; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
package SOAP::XMLSchema1999::Serializer; |
58
|
|
|
|
|
|
|
|
59
|
25
|
|
|
25
|
|
123
|
use vars qw(@EXPORT $AUTOLOAD); |
|
25
|
|
|
|
|
45
|
|
|
25
|
|
|
|
|
2696
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub AUTOLOAD { |
62
|
61
|
|
|
61
|
|
20023
|
local($1,$2); |
63
|
61
|
|
|
|
|
437
|
my($package, $method) = $AUTOLOAD =~ m/(?:(.+)::)([^:]+)$/; |
64
|
61
|
100
|
|
|
|
185
|
return if $method eq 'DESTROY'; |
65
|
25
|
|
|
25
|
|
129
|
no strict 'refs'; |
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
5928
|
|
66
|
|
|
|
|
|
|
|
67
|
60
|
|
|
|
|
94
|
my $export_var = $package . '::EXPORT'; |
68
|
60
|
|
|
|
|
431
|
my @export = @$export_var; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# Removed in 0.69 - this is a total hack. For some reason this is failing |
71
|
|
|
|
|
|
|
# despite not being a fatal error condition. |
72
|
|
|
|
|
|
|
# die "Type '$method' can't be found in a schema class '$package'\n" |
73
|
|
|
|
|
|
|
# unless $method =~ s/^as_// && grep {$_ eq $method} @{$export_var}; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# This was added in its place - it is still a hack, but it performs the |
76
|
|
|
|
|
|
|
# necessary substitution. It just does not die. |
77
|
60
|
100
|
66
|
|
|
309
|
if ($method =~ s/^as_// && grep {$_ eq $method} @{$export_var}) { |
|
2065
|
|
|
|
|
2637
|
|
|
58
|
|
|
|
|
163
|
|
78
|
|
|
|
|
|
|
# print STDERR "method is now '$method'\n"; |
79
|
|
|
|
|
|
|
} else { |
80
|
2
|
|
|
|
|
14
|
return; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
58
|
|
|
|
|
98
|
$method =~ s/_/-/; # fix ur-type |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
*$AUTOLOAD = sub { |
86
|
72
|
|
|
72
|
|
205
|
my $self = shift; |
87
|
72
|
|
|
|
|
123
|
my($value, $name, $type, $attr) = @_; |
88
|
72
|
|
|
|
|
516
|
return [$name, {'xsi:type' => "xsd:$method", %$attr}, $value]; |
89
|
58
|
|
|
|
|
481
|
}; |
90
|
58
|
|
|
|
|
326
|
goto &$AUTOLOAD; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
BEGIN { |
94
|
25
|
|
|
25
|
|
187
|
@EXPORT = qw(ur_type |
95
|
|
|
|
|
|
|
float double decimal timeDuration recurringDuration uriReference |
96
|
|
|
|
|
|
|
integer nonPositiveInteger negativeInteger long int short byte |
97
|
|
|
|
|
|
|
nonNegativeInteger unsignedLong unsignedInt unsignedShort unsignedByte |
98
|
|
|
|
|
|
|
positiveInteger timeInstant time timePeriod date month year century |
99
|
|
|
|
|
|
|
recurringDate recurringDay language |
100
|
|
|
|
|
|
|
base64 hex string boolean |
101
|
|
|
|
|
|
|
); |
102
|
|
|
|
|
|
|
# TODO: replace by symbol table operations... |
103
|
|
|
|
|
|
|
# predeclare subs, so ->can check will be positive |
104
|
25
|
|
|
|
|
67
|
foreach (@EXPORT) { eval "sub as_$_" } |
|
850
|
|
|
|
|
30850
|
|
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
25
|
|
|
25
|
|
114
|
sub nilValue { 'null' } |
108
|
|
|
|
|
|
|
|
109
|
1
|
|
|
1
|
|
110
|
sub anyTypeValue { 'ur-type' } |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub as_base64 { |
112
|
2
|
|
|
2
|
|
94
|
my ($self, $value, $name, $type, $attr) = @_; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# Fixes #30271 for 5.8 and above. |
115
|
|
|
|
|
|
|
# Won't fix for 5.6 and below - perl can't handle unicode before |
116
|
|
|
|
|
|
|
# 5.8, and applying pack() to everything is just a slowdown. |
117
|
2
|
50
|
|
|
|
7
|
if ($SOAP::Constants::HAS_ENCODE) { |
118
|
2
|
50
|
|
|
|
18
|
if (Encode::is_utf8($value)) { |
119
|
0
|
0
|
|
|
|
0
|
if (Encode->can('_utf8_off')) { # the quick way, but it may change in future Perl versions. |
120
|
0
|
|
|
|
|
0
|
Encode::_utf8_off($value); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
else { |
123
|
0
|
|
|
|
|
0
|
$value = pack('C*',unpack('C*',$value)); # the slow but safe way, |
124
|
|
|
|
|
|
|
# but this fallback works always. |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
2
|
|
|
|
|
19
|
require MIME::Base64; |
130
|
|
|
|
|
|
|
return [ |
131
|
2
|
|
|
|
|
20
|
$name, |
132
|
|
|
|
|
|
|
{ |
133
|
|
|
|
|
|
|
'xsi:type' => SOAP::Utils::qualify($self->encprefix => 'base64'), |
134
|
|
|
|
|
|
|
%$attr |
135
|
|
|
|
|
|
|
}, |
136
|
|
|
|
|
|
|
MIME::Base64::encode_base64($value,'') |
137
|
|
|
|
|
|
|
]; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub as_hex { |
141
|
1
|
|
|
1
|
|
4
|
my ($self, $value, $name, $type, $attr) = @_; |
142
|
|
|
|
|
|
|
return [ |
143
|
2
|
|
|
|
|
17
|
$name, |
144
|
|
|
|
|
|
|
{ |
145
|
|
|
|
|
|
|
'xsi:type' => 'xsd:hex', %$attr |
146
|
|
|
|
|
|
|
}, |
147
|
|
|
|
|
|
|
join '', map { |
148
|
1
|
|
|
|
|
6
|
uc sprintf "%02x", ord |
149
|
|
|
|
|
|
|
} split '', $value |
150
|
|
|
|
|
|
|
]; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub as_long { |
154
|
4
|
|
|
4
|
|
620
|
my($self, $value, $name, $type, $attr) = @_; |
155
|
|
|
|
|
|
|
return [ |
156
|
4
|
|
|
|
|
31
|
$name, |
157
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:long', %$attr}, |
158
|
|
|
|
|
|
|
$value |
159
|
|
|
|
|
|
|
]; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub as_dateTime { |
163
|
1
|
|
|
1
|
|
57
|
my ($self, $value, $name, $type, $attr) = @_; |
164
|
1
|
|
|
|
|
8
|
return [$name, {'xsi:type' => 'xsd:dateTime', %$attr}, $value]; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub as_string { |
168
|
10
|
|
|
10
|
|
1139
|
my ($self, $value, $name, $type, $attr) = @_; |
169
|
10
|
100
|
|
|
|
29
|
die "String value expected instead of @{[ref $value]} reference\n" |
|
1
|
|
|
|
|
10
|
|
170
|
|
|
|
|
|
|
if ref $value; |
171
|
|
|
|
|
|
|
return [ |
172
|
9
|
|
|
|
|
41
|
$name, |
173
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:string', %$attr}, |
174
|
|
|
|
|
|
|
SOAP::Utils::encode_data($value) |
175
|
|
|
|
|
|
|
]; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub as_anyURI { |
179
|
5
|
|
|
5
|
|
2075
|
my($self, $value, $name, $type, $attr) = @_; |
180
|
5
|
100
|
|
|
|
21
|
die "String value expected instead of @{[ref $value]} reference\n" if ref $value; |
|
1
|
|
|
|
|
8
|
|
181
|
|
|
|
|
|
|
return [ |
182
|
4
|
|
|
|
|
22
|
$name, |
183
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:anyURI', %$attr}, |
184
|
|
|
|
|
|
|
SOAP::Utils::encode_data($value) |
185
|
|
|
|
|
|
|
]; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
2
|
100
|
|
2
|
|
86
|
sub as_undef { $_[1] ? '1' : '0' } |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub as_boolean { |
191
|
2
|
|
|
2
|
|
122
|
my $self = shift; |
192
|
2
|
|
|
|
|
6
|
my($value, $name, $type, $attr) = @_; |
193
|
|
|
|
|
|
|
# fix [ 1.05279 ] Boolean serialization error |
194
|
|
|
|
|
|
|
return [ |
195
|
2
|
100
|
66
|
|
|
20
|
$name, |
196
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:boolean', %$attr}, |
197
|
|
|
|
|
|
|
( $value && $value ne 'false' ) ? 'true' : 'false' |
198
|
|
|
|
|
|
|
]; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub as_float { |
202
|
2
|
|
|
2
|
|
605
|
my($self, $value, $name, $type, $attr) = @_; |
203
|
|
|
|
|
|
|
return [ |
204
|
2
|
|
|
|
|
11
|
$name, |
205
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:float', %$attr}, |
206
|
|
|
|
|
|
|
$value |
207
|
|
|
|
|
|
|
]; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
package SOAP::XMLSchema2001::Serializer; |
213
|
|
|
|
|
|
|
|
214
|
25
|
|
|
25
|
|
152
|
use vars qw(@EXPORT); |
|
25
|
|
|
|
|
40
|
|
|
25
|
|
|
|
|
2686
|
|
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# no more warnings about "used only once" |
217
|
|
|
|
|
|
|
*AUTOLOAD if 0; |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
*AUTOLOAD = \&SOAP::XMLSchema1999::Serializer::AUTOLOAD; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
BEGIN { |
222
|
25
|
|
|
25
|
|
162
|
@EXPORT = qw(anyType anySimpleType float double decimal dateTime |
223
|
|
|
|
|
|
|
timePeriod gMonth gYearMonth gYear century |
224
|
|
|
|
|
|
|
gMonthDay gDay duration recurringDuration anyURI |
225
|
|
|
|
|
|
|
language integer nonPositiveInteger negativeInteger |
226
|
|
|
|
|
|
|
long int short byte nonNegativeInteger unsignedLong |
227
|
|
|
|
|
|
|
unsignedInt unsignedShort unsignedByte positiveInteger |
228
|
|
|
|
|
|
|
date time string hex base64 boolean |
229
|
|
|
|
|
|
|
QName |
230
|
|
|
|
|
|
|
); |
231
|
|
|
|
|
|
|
# Add QName to @EXPORT |
232
|
|
|
|
|
|
|
# predeclare subs, so ->can check will be positive |
233
|
25
|
|
|
|
|
50
|
foreach (@EXPORT) { eval "sub as_$_" } |
|
925
|
|
|
|
|
44163
|
|
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
47
|
|
|
47
|
|
179
|
sub nilValue { 'nil' } |
237
|
|
|
|
|
|
|
|
238
|
0
|
|
|
0
|
|
0
|
sub anyTypeValue { 'anyType' } |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub as_long; *as_long = \&SOAP::XMLSchema1999::Serializer::as_long; |
241
|
|
|
|
|
|
|
sub as_float; *as_float = \&SOAP::XMLSchema1999::Serializer::as_float; |
242
|
|
|
|
|
|
|
sub as_string; *as_string = \&SOAP::XMLSchema1999::Serializer::as_string; |
243
|
|
|
|
|
|
|
sub as_anyURI; *as_anyURI = \&SOAP::XMLSchema1999::Serializer::as_anyURI; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# TODO - QNames still don't work for 2001 schema! |
246
|
|
|
|
|
|
|
sub as_QName; *as_QName = \&SOAP::XMLSchema1999::Serializer::as_string; |
247
|
|
|
|
|
|
|
sub as_hex; *as_hex = \&as_hexBinary; |
248
|
|
|
|
|
|
|
sub as_base64; *as_base64 = \&as_base64Binary; |
249
|
|
|
|
|
|
|
sub as_timeInstant; *as_timeInstant = \&as_dateTime; |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# only 0 and 1 allowed - that's easy... |
252
|
|
|
|
|
|
|
sub as_undef { |
253
|
22
|
50
|
|
22
|
|
192
|
$_[1] |
254
|
|
|
|
|
|
|
? 'true' |
255
|
|
|
|
|
|
|
: 'false' |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub as_hexBinary { |
259
|
0
|
|
|
0
|
|
0
|
my ($self, $value, $name, $type, $attr) = @_; |
260
|
|
|
|
|
|
|
return [ |
261
|
0
|
|
|
|
|
0
|
$name, |
262
|
|
|
|
|
|
|
{'xsi:type' => 'xsd:hexBinary', %$attr}, |
263
|
|
|
|
|
|
|
join '', map { |
264
|
0
|
|
|
|
|
0
|
uc sprintf "%02x", ord |
265
|
|
|
|
|
|
|
} split '', $value |
266
|
|
|
|
|
|
|
]; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub as_base64Binary { |
270
|
1
|
|
|
1
|
|
9
|
my ($self, $value, $name, $type, $attr) = @_; |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# Fixes #30271 for 5.8 and above. |
273
|
|
|
|
|
|
|
# Won't fix for 5.6 and below - perl can't handle unicode before |
274
|
|
|
|
|
|
|
# 5.8, and applying pack() to everything is just a slowdown. |
275
|
1
|
50
|
|
|
|
112
|
if (eval "require Encode; 1") { |
276
|
1
|
50
|
|
|
|
5
|
if (Encode::is_utf8($value)) { |
277
|
0
|
0
|
|
|
|
0
|
if (Encode->can('_utf8_off')) { # the quick way, but it may change in future Perl versions. |
278
|
0
|
|
|
|
|
0
|
Encode::_utf8_off($value); |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
else { |
281
|
0
|
|
|
|
|
0
|
$value = pack('C*',unpack('C*',$value)); # the slow but safe way, |
282
|
|
|
|
|
|
|
# but this fallback works always. |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
1
|
|
|
|
|
44
|
require MIME::Base64; |
288
|
|
|
|
|
|
|
return [ |
289
|
1
|
|
|
|
|
16
|
$name, |
290
|
|
|
|
|
|
|
{ |
291
|
|
|
|
|
|
|
'xsi:type' => 'xsd:base64Binary', %$attr |
292
|
|
|
|
|
|
|
}, |
293
|
|
|
|
|
|
|
MIME::Base64::encode_base64($value,'') |
294
|
|
|
|
|
|
|
]; |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub as_boolean { |
298
|
2
|
|
|
2
|
|
5
|
my ($self, $value, $name, $type, $attr) = @_; |
299
|
|
|
|
|
|
|
# fix [ 1.05279 ] Boolean serialization error |
300
|
|
|
|
|
|
|
return [ |
301
|
2
|
100
|
66
|
|
|
28
|
$name, |
302
|
|
|
|
|
|
|
{ |
303
|
|
|
|
|
|
|
'xsi:type' => 'xsd:boolean', %$attr |
304
|
|
|
|
|
|
|
}, |
305
|
|
|
|
|
|
|
( $value && ($value ne 'false') ) |
306
|
|
|
|
|
|
|
? 'true' |
307
|
|
|
|
|
|
|
: 'false' |
308
|
|
|
|
|
|
|
]; |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# ====================================================================== |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
package SOAP::Utils; |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub qualify { |
317
|
177
|
50
|
33
|
177
|
|
1468
|
$_[1] |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
318
|
|
|
|
|
|
|
? $_[1] =~ /:/ |
319
|
|
|
|
|
|
|
? $_[1] |
320
|
|
|
|
|
|
|
: join(':', $_[0] || (), $_[1]) |
321
|
|
|
|
|
|
|
: defined $_[1] |
322
|
|
|
|
|
|
|
? $_[0] |
323
|
|
|
|
|
|
|
: '' |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub overqualify (&$) { |
327
|
0
|
|
|
0
|
|
0
|
for ($_[1]) { |
328
|
0
|
|
|
|
|
0
|
&{$_[0]}; |
|
0
|
|
|
|
|
0
|
|
329
|
0
|
|
|
|
|
0
|
s/^:|:$//g |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
sub disqualify { |
334
|
106
|
|
|
106
|
|
1305
|
(my $qname = shift) =~ s/^($SOAP::Constants::NSMASK?)://; |
335
|
106
|
|
|
|
|
600
|
return $qname; |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub splitqname { |
339
|
84
|
|
|
84
|
|
225
|
local($1,$2); |
340
|
84
|
|
|
|
|
343
|
$_[0] =~ /^(?:([^:]+):)?(.+)$/; |
341
|
84
|
|
|
|
|
304
|
return ($1,$2) |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub longname { |
345
|
0
|
0
|
|
0
|
|
0
|
defined $_[0] |
346
|
|
|
|
|
|
|
? sprintf('{%s}%s', $_[0], $_[1]) |
347
|
|
|
|
|
|
|
: $_[1] |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub splitlongname { |
351
|
71
|
|
|
71
|
|
207
|
local($1,$2); |
352
|
71
|
|
|
|
|
308
|
$_[0] =~ /^(?:\{(.*)\})?(.+)$/; |
353
|
71
|
|
|
|
|
302
|
return ($1,$2) |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
# Q: why only '&' and '<' are encoded, but not '>'? |
357
|
|
|
|
|
|
|
# A: because it is not required according to XML spec. |
358
|
|
|
|
|
|
|
# |
359
|
|
|
|
|
|
|
# [http://www.w3.org/TR/REC-xml#syntax] |
360
|
|
|
|
|
|
|
# The ampersand character (&) and the left angle bracket (<) may appear in |
361
|
|
|
|
|
|
|
# their literal form only when used as markup delimiters, or within a comment, |
362
|
|
|
|
|
|
|
# a processing instruction, or a CDATA section. If they are needed elsewhere, |
363
|
|
|
|
|
|
|
# they must be escaped using either numeric character references or the |
364
|
|
|
|
|
|
|
# strings "&" and "<" respectively. The right angle bracket (>) may be |
365
|
|
|
|
|
|
|
# represented using the string ">", and must, for compatibility, be |
366
|
|
|
|
|
|
|
# escaped using ">" or a character reference when it appears in the |
367
|
|
|
|
|
|
|
# string "]]>" in content, when that string is not marking the end of a |
368
|
|
|
|
|
|
|
# CDATA section. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
my %encode_attribute = ('&' => '&', '>' => '>', '<' => '<', '"' => '"'); |
371
|
149
|
|
|
149
|
|
285
|
sub encode_attribute { (my $e = $_[0]) =~ s/([&<>\"])/$encode_attribute{$1}/g; $e } |
|
149
|
|
|
|
|
550
|
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
my %encode_data = ('&' => '&', '>' => '>', '<' => '<', "\xd" => '
'); |
374
|
|
|
|
|
|
|
sub encode_data { |
375
|
27
|
|
|
27
|
|
77
|
my $e = $_[0]; |
376
|
27
|
100
|
|
|
|
73
|
if ($e) { |
377
|
11
|
|
|
|
|
28
|
$e =~ s/([&<>\015])/$encode_data{$1}/g; |
378
|
11
|
|
|
|
|
19
|
$e =~ s/\]\]>/\]\]>/g; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
$e |
381
|
27
|
|
|
|
|
157
|
} |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
# methods for internal tree (SOAP::Deserializer, SOAP::SOM and SOAP::Serializer) |
384
|
|
|
|
|
|
|
|
385
|
0
|
|
|
0
|
|
0
|
sub o_qname { $_[0]->[0] } |
386
|
0
|
|
|
0
|
|
0
|
sub o_attr { $_[0]->[1] } |
387
|
0
|
0
|
|
0
|
|
0
|
sub o_child { ref $_[0]->[2] ? $_[0]->[2] : undef } |
388
|
0
|
0
|
|
0
|
|
0
|
sub o_chars { ref $_[0]->[2] ? undef : $_[0]->[2] } |
389
|
|
|
|
|
|
|
# $_[0]->[3] is not used. Serializer stores object ID there |
390
|
0
|
|
|
0
|
|
0
|
sub o_value { $_[0]->[4] } |
391
|
0
|
|
|
0
|
|
0
|
sub o_lname { $_[0]->[5] } |
392
|
0
|
|
|
0
|
|
0
|
sub o_lattr { $_[0]->[6] } |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub format_datetime { |
395
|
0
|
|
|
0
|
|
0
|
my ($s,$m,$h,$D,$M,$Y) = (@_)[0,1,2,3,4,5]; |
396
|
0
|
|
|
|
|
0
|
my $time = sprintf("%04d-%02d-%02dT%02d:%02d:%02d",($Y+1900),($M+1),$D,$h,$m,$s); |
397
|
0
|
|
|
|
|
0
|
return $time; |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
# make bytelength that calculates length in bytes regardless of utf/byte settings |
401
|
|
|
|
|
|
|
# either we can do 'use bytes' or length will count bytes already |
402
|
|
|
|
|
|
|
BEGIN { |
403
|
|
|
|
|
|
|
sub bytelength; |
404
|
|
|
|
|
|
|
*bytelength = eval('use bytes; 1') # 5.6.0 and later? |
405
|
25
|
50
|
|
25
|
|
17394
|
? sub { use bytes; length(@_ ? $_[0] : $_) } |
|
25
|
|
|
11
|
|
232
|
|
|
25
|
|
|
|
|
138
|
|
|
11
|
|
|
|
|
64
|
|
406
|
25
|
0
|
|
25
|
|
2965
|
: sub { length(@_ ? $_[0] : $_) }; |
|
0
|
50
|
|
25
|
|
0
|
|
|
25
|
|
|
|
|
122
|
|
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
98
|
|
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# ====================================================================== |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
package SOAP::Cloneable; |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub clone { |
414
|
24
|
|
|
24
|
|
36
|
my $self = shift; |
415
|
|
|
|
|
|
|
|
416
|
24
|
50
|
33
|
|
|
130
|
return unless ref $self && UNIVERSAL::isa($self => __PACKAGE__); |
417
|
|
|
|
|
|
|
|
418
|
24
|
|
33
|
|
|
79
|
my $clone = bless {} => ref($self) || $self; |
419
|
24
|
|
|
|
|
193
|
for (keys %$self) { |
420
|
199
|
|
|
|
|
211
|
my $value = $self->{$_}; |
421
|
199
|
100
|
100
|
|
|
821
|
$clone->{$_} = ref $value && UNIVERSAL::isa($value => __PACKAGE__) ? $value->clone : $value; |
422
|
|
|
|
|
|
|
} |
423
|
24
|
|
|
|
|
64
|
return $clone; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
# ====================================================================== |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
package SOAP::Transport; |
429
|
|
|
|
|
|
|
|
430
|
25
|
|
|
25
|
|
123
|
use vars qw($AUTOLOAD @ISA); |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
1494
|
|
431
|
|
|
|
|
|
|
@ISA = qw(SOAP::Cloneable); |
432
|
|
|
|
|
|
|
|
433
|
25
|
|
|
25
|
|
13389
|
use Class::Inspector; |
|
25
|
|
|
|
|
82346
|
|
|
25
|
|
|
|
|
6359
|
|
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
|
436
|
15
|
|
|
15
|
|
47
|
sub DESTROY { SOAP::Trace::objects('()') } |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
sub new { |
439
|
15
|
|
|
15
|
|
31
|
my $self = shift; |
440
|
15
|
50
|
|
|
|
48
|
return $self if ref $self; |
441
|
15
|
|
33
|
|
|
92
|
my $class = ref($self) || $self; |
442
|
|
|
|
|
|
|
|
443
|
15
|
|
|
|
|
57
|
SOAP::Trace::objects('()'); |
444
|
15
|
|
|
|
|
120
|
return bless {} => $class; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
sub proxy { |
448
|
84
|
|
|
84
|
|
126
|
my $self = shift; |
449
|
84
|
50
|
|
|
|
232
|
$self = $self->new() if not ref $self; |
450
|
|
|
|
|
|
|
|
451
|
84
|
|
|
|
|
129
|
my $class = ref $self; |
452
|
|
|
|
|
|
|
|
453
|
84
|
100
|
|
|
|
860
|
return $self->{_proxy} unless @_; |
454
|
|
|
|
|
|
|
|
455
|
13
|
50
|
|
|
|
135
|
$_[0] =~ /^(\w+):/ or die "proxy: transport protocol not specified\n"; |
456
|
13
|
|
|
|
|
71
|
my $protocol = uc "$1"; # untainted now |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
# HTTPS is handled by HTTP class |
459
|
13
|
|
|
|
|
35
|
$protocol =~s/^HTTPS$/HTTP/; |
460
|
|
|
|
|
|
|
|
461
|
13
|
|
|
|
|
55
|
(my $protocol_class = "${class}::$protocol") =~ s/-/_/g; |
462
|
|
|
|
|
|
|
|
463
|
25
|
|
|
25
|
|
185
|
no strict 'refs'; |
|
25
|
|
|
|
|
41
|
|
|
25
|
|
|
|
|
4924
|
|
464
|
13
|
50
|
33
|
|
|
140
|
unless (Class::Inspector->loaded("$protocol_class\::Client") |
465
|
|
|
|
|
|
|
&& UNIVERSAL::can("$protocol_class\::Client" => 'new') |
466
|
|
|
|
|
|
|
) { |
467
|
13
|
|
|
|
|
2227
|
eval "require $protocol_class"; |
468
|
13
|
50
|
|
|
|
93
|
die "Unsupported protocol '$protocol'\n" |
469
|
|
|
|
|
|
|
if $@ =~ m!^Can\'t locate SOAP/Transport/!; |
470
|
13
|
50
|
|
|
|
51
|
die if $@; |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
|
473
|
13
|
|
|
|
|
43
|
$protocol_class .= "::Client"; |
474
|
13
|
|
|
|
|
98
|
return $self->{_proxy} = $protocol_class->new(endpoint => shift, @_); |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
sub AUTOLOAD { |
478
|
46
|
|
|
46
|
|
207
|
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); |
479
|
46
|
50
|
|
|
|
142
|
return if $method eq 'DESTROY'; |
480
|
|
|
|
|
|
|
|
481
|
25
|
|
|
25
|
|
130
|
no strict 'refs'; |
|
25
|
|
|
|
|
51
|
|
|
25
|
|
|
|
|
2145
|
|
482
|
46
|
|
|
47
|
|
357
|
*$AUTOLOAD = sub { shift->proxy->$method(@_) }; |
|
47
|
|
|
|
|
157
|
|
483
|
46
|
|
|
|
|
183
|
goto &$AUTOLOAD; |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
# ====================================================================== |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
package SOAP::Fault; |
489
|
|
|
|
|
|
|
|
490
|
25
|
|
|
25
|
|
134
|
use Carp (); |
|
25
|
|
|
|
|
29
|
|
|
25
|
|
|
|
|
597
|
|
491
|
|
|
|
|
|
|
|
492
|
25
|
|
|
25
|
|
29728
|
use overload fallback => 1, '""' => "stringify"; |
|
25
|
|
|
|
|
22571
|
|
|
25
|
|
|
|
|
155
|
|
493
|
|
|
|
|
|
|
|
494
|
0
|
|
|
0
|
|
0
|
sub DESTROY { SOAP::Trace::objects('()') } |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
sub new { |
497
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
498
|
|
|
|
|
|
|
|
499
|
0
|
0
|
|
|
|
0
|
unless (ref $self) { |
500
|
0
|
|
|
|
|
0
|
my $class = $self; |
501
|
0
|
|
|
|
|
0
|
$self = bless {} => $class; |
502
|
0
|
|
|
|
|
0
|
SOAP::Trace::objects('()'); |
503
|
|
|
|
|
|
|
} |
504
|
|
|
|
|
|
|
|
505
|
0
|
0
|
0
|
|
|
0
|
Carp::carp "Odd (wrong?) number of parameters in new()" |
506
|
|
|
|
|
|
|
if $^W && (@_ & 1); |
507
|
|
|
|
|
|
|
|
508
|
25
|
|
|
25
|
|
3753
|
no strict qw(refs); |
|
25
|
|
|
|
|
50
|
|
|
25
|
|
|
|
|
2806
|
|
509
|
0
|
|
|
|
|
0
|
while (@_) { |
510
|
0
|
|
|
|
|
0
|
my $method = shift; |
511
|
0
|
0
|
|
|
|
0
|
$self->$method(shift) |
512
|
|
|
|
|
|
|
if $self->can($method) |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
|
515
|
0
|
|
|
|
|
0
|
return $self; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
sub stringify { |
519
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
520
|
0
|
|
|
|
|
0
|
return join ': ', $self->faultcode, $self->faultstring; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub BEGIN { |
524
|
25
|
|
|
25
|
|
149
|
no strict 'refs'; |
|
25
|
|
|
|
|
40
|
|
|
25
|
|
|
|
|
3151
|
|
525
|
25
|
|
|
25
|
|
72
|
for my $method (qw(faultcode faultstring faultactor faultdetail)) { |
526
|
100
|
|
|
|
|
196
|
my $field = '_' . $method; |
527
|
|
|
|
|
|
|
*$method = sub { |
528
|
0
|
0
|
|
0
|
|
0
|
my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) |
529
|
|
|
|
|
|
|
? shift->new |
530
|
|
|
|
|
|
|
: __PACKAGE__->new; |
531
|
0
|
0
|
|
|
|
0
|
if (@_) { |
532
|
0
|
|
|
|
|
0
|
$self->{$field} = shift; |
533
|
0
|
|
|
|
|
0
|
return $self |
534
|
|
|
|
|
|
|
} |
535
|
0
|
|
|
|
|
0
|
return $self->{$field}; |
536
|
|
|
|
|
|
|
} |
537
|
100
|
|
|
|
|
591
|
} |
538
|
25
|
|
|
|
|
872
|
*detail = \&faultdetail; |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# ====================================================================== |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
package SOAP::Data; |
544
|
|
|
|
|
|
|
|
545
|
25
|
|
|
25
|
|
134
|
use vars qw(@ISA @EXPORT_OK); |
|
25
|
|
|
|
|
45
|
|
|
25
|
|
|
|
|
1449
|
|
546
|
25
|
|
|
25
|
|
123
|
use Exporter; |
|
25
|
|
|
|
|
44
|
|
|
25
|
|
|
|
|
1181
|
|
547
|
25
|
|
|
25
|
|
109
|
use Carp (); |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
537
|
|
548
|
25
|
|
|
25
|
|
11508
|
use SOAP::Lite::Deserializer::XMLSchemaSOAP1_2; |
|
25
|
|
|
|
|
271
|
|
|
25
|
|
|
|
|
2848
|
|
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
551
|
|
|
|
|
|
|
@EXPORT_OK = qw(name type attr value uri); |
552
|
|
|
|
|
|
|
|
553
|
100
|
|
|
100
|
|
394
|
sub DESTROY { SOAP::Trace::objects('()') } |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
sub new { |
556
|
206
|
|
|
206
|
|
1589
|
my $self = shift; |
557
|
|
|
|
|
|
|
|
558
|
206
|
100
|
|
|
|
405
|
unless (ref $self) { |
559
|
100
|
|
|
|
|
111
|
my $class = $self; |
560
|
100
|
|
|
|
|
417
|
$self = bless {_attr => {}, _value => [], _signature => []} => $class; |
561
|
100
|
|
|
|
|
198
|
SOAP::Trace::objects('()'); |
562
|
|
|
|
|
|
|
} |
563
|
25
|
|
|
25
|
|
133
|
no strict qw(refs); |
|
25
|
|
|
|
|
45
|
|
|
25
|
|
|
|
|
12388
|
|
564
|
206
|
50
|
33
|
|
|
589
|
Carp::carp "Odd (wrong?) number of parameters in new()" if $^W && (@_ & 1); |
565
|
206
|
|
|
|
|
426
|
while (@_) { |
566
|
0
|
|
|
|
|
0
|
my $method = shift; |
567
|
0
|
0
|
|
|
|
0
|
$self->$method(shift) if $self->can($method) |
568
|
|
|
|
|
|
|
} |
569
|
|
|
|
|
|
|
|
570
|
206
|
|
|
|
|
300
|
return $self; |
571
|
|
|
|
|
|
|
} |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
sub name { |
574
|
297
|
50
|
|
297
|
|
901
|
my $self = ref $_[0] ? shift : UNIVERSAL::isa($_[0] => __PACKAGE__) ? shift->new : __PACKAGE__->new; |
|
|
100
|
|
|
|
|
|
575
|
297
|
100
|
|
|
|
507
|
if (@_) { |
576
|
99
|
|
|
|
|
114
|
my $name = shift; |
577
|
99
|
|
|
|
|
103
|
my ($uri, $prefix); # predeclare, because can't declare in assign |
578
|
99
|
100
|
|
|
|
185
|
if ($name) { |
579
|
71
|
|
|
|
|
156
|
($uri, $name) = SOAP::Utils::splitlongname($name); |
580
|
71
|
50
|
|
|
|
180
|
unless (defined $uri) { |
581
|
71
|
|
|
|
|
136
|
($prefix, $name) = SOAP::Utils::splitqname($name); |
582
|
71
|
100
|
|
|
|
296
|
$self->prefix($prefix) if defined $prefix; |
583
|
|
|
|
|
|
|
} else { |
584
|
0
|
|
|
|
|
0
|
$self->uri($uri); |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
} |
587
|
99
|
|
|
|
|
254
|
$self->{_name} = $name; |
588
|
|
|
|
|
|
|
|
589
|
99
|
100
|
|
|
|
301
|
$self->value(@_) if @_; |
590
|
99
|
|
|
|
|
377
|
return $self; |
591
|
|
|
|
|
|
|
} |
592
|
198
|
|
|
|
|
492
|
return $self->{_name}; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub attr { |
596
|
132
|
0
|
|
132
|
|
289
|
my $self = ref $_[0] |
|
|
50
|
|
|
|
|
|
597
|
|
|
|
|
|
|
? shift |
598
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
599
|
|
|
|
|
|
|
? shift->new() |
600
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
601
|
132
|
100
|
|
|
|
264
|
if (@_) { |
602
|
32
|
|
|
|
|
89
|
$self->{_attr} = shift; |
603
|
32
|
50
|
|
|
|
98
|
return $self->value(@_) if @_; |
604
|
32
|
|
|
|
|
137
|
return $self |
605
|
|
|
|
|
|
|
} |
606
|
100
|
|
|
|
|
418
|
return $self->{_attr}; |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
sub type { |
610
|
311
|
0
|
|
311
|
|
570
|
my $self = ref $_[0] |
|
|
50
|
|
|
|
|
|
611
|
|
|
|
|
|
|
? shift |
612
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
613
|
|
|
|
|
|
|
? shift->new() |
614
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
615
|
311
|
100
|
|
|
|
554
|
if (@_) { |
616
|
5
|
|
|
|
|
55
|
$self->{_type} = shift; |
617
|
5
|
50
|
|
|
|
13
|
$self->value(@_) if @_; |
618
|
5
|
|
|
|
|
35
|
return $self; |
619
|
|
|
|
|
|
|
} |
620
|
306
|
50
|
66
|
|
|
848
|
if (!defined $self->{_type} && (my @types = grep {/^\{$SOAP::Constants::NS_XSI_ALL}type$/o} keys %{$self->{_attr}})) { |
|
102
|
|
|
|
|
1039
|
|
|
296
|
|
|
|
|
906
|
|
621
|
0
|
|
|
|
|
0
|
$self->{_type} = (SOAP::Utils::splitlongname(delete $self->{_attr}->{shift(@types)}))[1]; |
622
|
|
|
|
|
|
|
} |
623
|
306
|
|
|
|
|
1471
|
return $self->{_type}; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
BEGIN { |
627
|
25
|
|
|
25
|
|
164
|
no strict 'refs'; |
|
25
|
|
|
|
|
41
|
|
|
25
|
|
|
|
|
8495
|
|
628
|
25
|
|
|
25
|
|
71
|
for my $method (qw(root mustUnderstand)) { |
629
|
50
|
|
|
|
|
91
|
my $field = '_' . $method; |
630
|
|
|
|
|
|
|
*$method = sub { |
631
|
2
|
100
|
|
2
|
|
317
|
my $attr = $method eq 'root' |
632
|
|
|
|
|
|
|
? "{$SOAP::Constants::NS_ENC}$method" |
633
|
|
|
|
|
|
|
: "{$SOAP::Constants::NS_ENV}$method"; |
634
|
2
|
50
|
|
|
|
14
|
my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) |
635
|
|
|
|
|
|
|
? shift->new |
636
|
|
|
|
|
|
|
: __PACKAGE__->new; |
637
|
2
|
50
|
|
|
|
6
|
if (@_) { |
638
|
2
|
50
|
|
|
|
12
|
$self->{_attr}->{$attr} = $self->{$field} = shift() ? 1 : 0; |
639
|
2
|
100
|
|
|
|
8
|
$self->value(@_) if @_; |
640
|
2
|
|
|
|
|
10
|
return $self; |
641
|
|
|
|
|
|
|
} |
642
|
0
|
0
|
0
|
|
|
0
|
$self->{$field} = SOAP::Lite::Deserializer::XMLSchemaSOAP1_2->as_boolean($self->{_attr}->{$attr}) |
643
|
|
|
|
|
|
|
if !defined $self->{$field} && defined $self->{_attr}->{$attr}; |
644
|
0
|
|
|
|
|
0
|
return $self->{$field}; |
645
|
|
|
|
|
|
|
} |
646
|
50
|
|
|
|
|
363
|
} |
647
|
|
|
|
|
|
|
|
648
|
25
|
|
|
|
|
47
|
for my $method (qw(actor encodingStyle)) { |
649
|
50
|
|
|
|
|
100
|
my $field = '_' . $method; |
650
|
|
|
|
|
|
|
*$method = sub { |
651
|
0
|
|
|
0
|
|
0
|
my $attr = "{$SOAP::Constants::NS_ENV}$method"; |
652
|
0
|
0
|
|
|
|
0
|
my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) |
653
|
|
|
|
|
|
|
? shift->new() |
654
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
655
|
0
|
0
|
|
|
|
0
|
if (@_) { |
656
|
0
|
|
|
|
|
0
|
$self->{_attr}->{$attr} = $self->{$field} = shift; |
657
|
0
|
0
|
|
|
|
0
|
$self->value(@_) if @_; |
658
|
0
|
|
|
|
|
0
|
return $self; |
659
|
|
|
|
|
|
|
} |
660
|
0
|
0
|
0
|
|
|
0
|
$self->{$field} = $self->{_attr}->{$attr} |
661
|
|
|
|
|
|
|
if !defined $self->{$field} && defined $self->{_attr}->{$attr}; |
662
|
0
|
|
|
|
|
0
|
return $self->{$field}; |
663
|
|
|
|
|
|
|
} |
664
|
50
|
|
|
|
|
10912
|
} |
665
|
|
|
|
|
|
|
} |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
sub prefix { |
668
|
142
|
0
|
|
142
|
|
270
|
my $self = ref $_[0] |
|
|
50
|
|
|
|
|
|
669
|
|
|
|
|
|
|
? shift |
670
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
671
|
|
|
|
|
|
|
? shift->new() |
672
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
673
|
142
|
100
|
|
|
|
372
|
return $self->{_prefix} unless @_; |
674
|
43
|
|
|
|
|
101
|
$self->{_prefix} = shift; |
675
|
43
|
50
|
|
|
|
118
|
if (scalar @_) { |
676
|
0
|
|
|
|
|
0
|
return $self->value(@_); |
677
|
|
|
|
|
|
|
} |
678
|
43
|
|
|
|
|
83
|
return $self; |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
sub uri { |
682
|
99
|
0
|
|
99
|
|
203
|
my $self = ref $_[0] |
|
|
50
|
|
|
|
|
|
683
|
|
|
|
|
|
|
? shift |
684
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
685
|
|
|
|
|
|
|
? shift->new() |
686
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
687
|
99
|
50
|
|
|
|
390
|
return $self->{_uri} unless @_; |
688
|
0
|
|
|
|
|
0
|
my $uri = $self->{_uri} = shift; |
689
|
0
|
0
|
0
|
|
|
0
|
warn "Usage of '::' in URI ($uri) deprecated. Use '/' instead\n" |
|
|
|
0
|
|
|
|
|
690
|
|
|
|
|
|
|
if defined $uri && $^W && $uri =~ /::/; |
691
|
0
|
0
|
|
|
|
0
|
if (scalar @_) { |
692
|
0
|
|
|
|
|
0
|
return $self->value(@_); |
693
|
|
|
|
|
|
|
} |
694
|
0
|
|
|
|
|
0
|
return $self; |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
sub set_value { |
698
|
99
|
50
|
|
99
|
|
242
|
my $self = ref $_[0] |
|
|
100
|
|
|
|
|
|
699
|
|
|
|
|
|
|
? shift |
700
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
701
|
|
|
|
|
|
|
? shift->new() |
702
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
703
|
99
|
|
|
|
|
207
|
$self->{_value} = [@_]; |
704
|
99
|
|
|
|
|
221
|
return $self; |
705
|
|
|
|
|
|
|
} |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
sub value { |
708
|
174
|
50
|
|
174
|
|
1007
|
my $self = ref $_[0] ? shift |
|
|
100
|
|
|
|
|
|
709
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[0] => __PACKAGE__) |
710
|
|
|
|
|
|
|
? shift->new() |
711
|
|
|
|
|
|
|
: __PACKAGE__->new; |
712
|
174
|
100
|
|
|
|
305
|
if (@_) { |
713
|
74
|
|
|
|
|
162
|
return $self->set_value(@_); |
714
|
|
|
|
|
|
|
} |
715
|
|
|
|
|
|
|
else { |
716
|
|
|
|
|
|
|
return wantarray |
717
|
100
|
50
|
|
|
|
178
|
? @{$self->{_value}} |
|
100
|
|
|
|
|
317
|
|
718
|
|
|
|
|
|
|
: $self->{_value}->[0]; |
719
|
|
|
|
|
|
|
} |
720
|
|
|
|
|
|
|
} |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub signature { |
723
|
105
|
50
|
|
105
|
|
420
|
my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) |
724
|
|
|
|
|
|
|
? shift->new() |
725
|
|
|
|
|
|
|
: __PACKAGE__->new(); |
726
|
105
|
100
|
|
|
|
322
|
(@_) |
727
|
|
|
|
|
|
|
? ($self->{_signature} = shift, return $self) |
728
|
|
|
|
|
|
|
: (return $self->{_signature}); |
729
|
|
|
|
|
|
|
} |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
# ====================================================================== |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
package SOAP::Header; |
734
|
|
|
|
|
|
|
|
735
|
25
|
|
|
25
|
|
140
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
1705
|
|
736
|
|
|
|
|
|
|
@ISA = qw(SOAP::Data); |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# ====================================================================== |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
package SOAP::Serializer; |
741
|
25
|
|
|
25
|
|
10627
|
use SOAP::Lite::Utils; |
|
25
|
|
|
|
|
51
|
|
|
25
|
|
|
|
|
137
|
|
742
|
25
|
|
|
25
|
|
131
|
use Carp (); |
|
25
|
|
|
|
|
29
|
|
|
25
|
|
|
|
|
449
|
|
743
|
25
|
|
|
25
|
|
98
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
4554
|
|
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
@ISA = qw(SOAP::Cloneable SOAP::XMLSchema::Serializer); |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
BEGIN { |
748
|
|
|
|
|
|
|
# namespaces and anonymous data structures |
749
|
25
|
|
|
25
|
|
54
|
my $ns = 0; |
750
|
25
|
|
|
|
|
37
|
my $name = 0; |
751
|
25
|
|
|
|
|
666
|
my $prefix = 'c-'; |
752
|
11
|
|
|
11
|
|
63
|
sub gen_ns { 'namesp' . ++$ns } |
753
|
41
|
|
|
41
|
|
241
|
sub gen_name { join '', $prefix, 'gensym', ++$name } |
754
|
0
|
|
|
0
|
|
0
|
sub prefix { $prefix =~ s/^[^\-]+-/$_[1]-/; $_[0]; } |
|
0
|
|
|
|
|
0
|
|
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
sub BEGIN { |
758
|
25
|
|
|
25
|
|
132
|
no strict 'refs'; |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
2227
|
|
759
|
|
|
|
|
|
|
|
760
|
25
|
|
|
25
|
|
155
|
__PACKAGE__->__mk_accessors(qw(readable level seen autotype attr maptype |
761
|
|
|
|
|
|
|
namespaces multirefinplace encoding signature on_nonserialized context |
762
|
|
|
|
|
|
|
ns_uri ns_prefix use_default_ns)); |
763
|
|
|
|
|
|
|
|
764
|
25
|
|
|
|
|
40
|
for my $method (qw(method fault freeform)) { # aliases for envelope |
765
|
6
|
|
|
6
|
|
24
|
*$method = sub { shift->envelope($method => @_) } |
766
|
75
|
|
|
|
|
25391
|
} |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
# Is this necessary? Seems like work for nothing when a user could just use |
769
|
|
|
|
|
|
|
# SOAP::Utils directly. |
770
|
|
|
|
|
|
|
# for my $method (qw(qualify overqualify disqualify)) { # import from SOAP::Utils |
771
|
|
|
|
|
|
|
# *$method = \&{'SOAP::Utils::'.$method}; |
772
|
|
|
|
|
|
|
# } |
773
|
|
|
|
|
|
|
} |
774
|
|
|
|
|
|
|
|
775
|
25
|
|
|
25
|
|
179
|
sub DESTROY { SOAP::Trace::objects('()') } |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
sub new { |
778
|
183
|
|
|
183
|
|
336
|
my $self = shift; |
779
|
183
|
100
|
|
|
|
499
|
return $self if ref $self; |
780
|
|
|
|
|
|
|
|
781
|
25
|
|
|
|
|
48
|
my $class = $self; |
782
|
0
|
0
|
|
0
|
|
0
|
$self = bless { |
783
|
|
|
|
|
|
|
_level => 0, |
784
|
|
|
|
|
|
|
_autotype => 1, |
785
|
|
|
|
|
|
|
_readable => 0, |
786
|
|
|
|
|
|
|
_ns_uri => '', |
787
|
|
|
|
|
|
|
_ns_prefix => '', |
788
|
|
|
|
|
|
|
_use_default_ns => 1, |
789
|
|
|
|
|
|
|
_multirefinplace => 0, |
790
|
|
|
|
|
|
|
_seen => {}, |
791
|
|
|
|
|
|
|
_encoding => 'UTF-8', |
792
|
|
|
|
|
|
|
_objectstack => {}, |
793
|
|
|
|
|
|
|
_signature => [], |
794
|
|
|
|
|
|
|
_maptype => {}, |
795
|
0
|
|
|
|
|
0
|
_on_nonserialized => sub {Carp::carp "Cannot marshall @{[ref shift]} reference" if $^W; return}, |
|
0
|
|
|
|
|
0
|
|
796
|
25
|
|
|
|
|
385
|
_encodingStyle => $SOAP::Constants::NS_ENC, |
797
|
|
|
|
|
|
|
_attr => { |
798
|
|
|
|
|
|
|
"{$SOAP::Constants::NS_ENV}encodingStyle" => $SOAP::Constants::NS_ENC, |
799
|
|
|
|
|
|
|
}, |
800
|
|
|
|
|
|
|
_namespaces => {}, |
801
|
|
|
|
|
|
|
_soapversion => SOAP::Lite->soapversion, |
802
|
|
|
|
|
|
|
} => $class; |
803
|
28
|
|
|
28
|
|
158
|
$self->typelookup({ |
804
|
|
|
|
|
|
|
'base64Binary' => |
805
|
|
|
|
|
|
|
[10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/ }, 'as_base64Binary'], |
806
|
|
|
|
|
|
|
'zerostring' => |
807
|
28
|
100
|
100
|
28
|
|
105
|
[12, sub { $_[0] =~ /^0\d+$/ }, 'as_string'], |
|
27
|
|
|
|
|
450
|
|
808
|
|
|
|
|
|
|
# int (and actually long too) are subtle: the negative range is one greater... |
809
|
|
|
|
|
|
|
'int' => |
810
|
12
|
100
|
|
12
|
|
89
|
[20, sub {$_[0] =~ /^([+-]?\d+)$/ && ($1 <= 2147483647) && ($1 >= -2147483648); }, 'as_int'], |
811
|
|
|
|
|
|
|
'long' => |
812
|
10
|
|
|
10
|
|
52
|
[25, sub {$_[0] =~ /^([+-]?\d+)$/ && $1 <= 9223372036854775807;}, 'as_long'], |
813
|
|
|
|
|
|
|
'float' => |
814
|
|
|
|
|
|
|
[30, sub {$_[0] =~ /^(-?(?:\d+(?:\.\d*)?|\.\d+|NaN|INF)|([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)$/}, 'as_float'], |
815
|
|
|
|
|
|
|
'gMonth' => |
816
|
10
|
|
|
10
|
|
30
|
[35, sub { $_[0] =~ /^--\d\d--(-\d\d:\d\d)?$/; }, 'as_gMonth'], |
817
|
|
|
|
|
|
|
'gDay' => |
818
|
10
|
|
|
10
|
|
31
|
[40, sub { $_[0] =~ /^---\d\d(-\d\d:\d\d)?$/; }, 'as_gDay'], |
819
|
|
|
|
|
|
|
'gYear' => |
820
|
10
|
|
|
10
|
|
43
|
[45, sub { $_[0] =~ /^-?\d\d\d\d(-\d\d:\d\d)?$/; }, 'as_gYear'], |
821
|
|
|
|
|
|
|
'gMonthDay' => |
822
|
10
|
|
|
10
|
|
34
|
[50, sub { $_[0] =~ /^-\d\d-\d\d(-\d\d:\d\d)?$/; }, 'as_gMonthDay'], |
823
|
|
|
|
|
|
|
'gYearMonth' => |
824
|
10
|
|
|
10
|
|
31
|
[55, sub { $_[0] =~ /^-?\d\d\d\d-\d\d(Z|([+-]\d\d:\d\d))?$/; }, 'as_gYearMonth'], |
825
|
|
|
|
|
|
|
'date' => |
826
|
10
|
|
|
10
|
|
32
|
[60, sub { $_[0] =~ /^-?\d\d\d\d-\d\d-\d\d(Z|([+-]\d\d:\d\d))?$/; }, 'as_date'], |
827
|
|
|
|
|
|
|
'time' => |
828
|
10
|
|
|
10
|
|
30
|
[70, sub { $_[0] =~ /^\d\d:\d\d:\d\d(\.\d\d\d)?(Z|([+-]\d\d:\d\d))?$/; }, 'as_time'], |
829
|
|
|
|
|
|
|
'dateTime' => |
830
|
10
|
|
|
10
|
|
39
|
[75, sub { $_[0] =~ /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?(Z|([+-]\d\d:\d\d))?$/; }, 'as_dateTime'], |
831
|
|
|
|
|
|
|
'duration' => |
832
|
10
|
100
|
|
10
|
|
93
|
[80, sub { $_[0] !~m{^-?PT?$} && $_[0] =~ m{^ |
833
|
|
|
|
|
|
|
-? # a optional - sign |
834
|
|
|
|
|
|
|
P |
835
|
|
|
|
|
|
|
(:? \d+Y )? |
836
|
|
|
|
|
|
|
(:? \d+M )? |
837
|
|
|
|
|
|
|
(:? \d+D )? |
838
|
|
|
|
|
|
|
(:? |
839
|
|
|
|
|
|
|
T(:?\d+H)? |
840
|
|
|
|
|
|
|
(:?\d+M)? |
841
|
|
|
|
|
|
|
(:?\d+S)? |
842
|
|
|
|
|
|
|
)? |
843
|
|
|
|
|
|
|
$ |
844
|
|
|
|
|
|
|
}x; |
845
|
|
|
|
|
|
|
}, 'as_duration'], |
846
|
|
|
|
|
|
|
'boolean' => |
847
|
9
|
|
|
9
|
|
57
|
[90, sub { $_[0] =~ /^(true|false)$/i; }, 'as_boolean'], |
848
|
|
|
|
|
|
|
'anyURI' => |
849
|
7
|
|
|
7
|
|
40
|
[95, sub { $_[0] =~ /^(urn:|http:\/\/)/i; }, 'as_anyURI'], |
|
6
|
|
|
|
|
61
|
|
850
|
|
|
|
|
|
|
'string' => |
851
|
25
|
|
|
|
|
1606
|
[100, sub {1}, 'as_string'], |
852
|
|
|
|
|
|
|
}); |
853
|
25
|
|
|
|
|
130
|
$self->register_ns($SOAP::Constants::NS_ENC,$SOAP::Constants::PREFIX_ENC); |
854
|
25
|
50
|
|
|
|
116
|
$self->register_ns($SOAP::Constants::NS_ENV,$SOAP::Constants::PREFIX_ENV) |
855
|
|
|
|
|
|
|
if $SOAP::Constants::PREFIX_ENV; |
856
|
25
|
|
|
|
|
118
|
$self->xmlschema($SOAP::Constants::DEFAULT_XML_SCHEMA); |
857
|
25
|
|
|
|
|
67
|
SOAP::Trace::objects('()'); |
858
|
|
|
|
|
|
|
|
859
|
25
|
|
|
25
|
|
212
|
no strict qw(refs); |
|
25
|
|
|
|
|
39
|
|
|
25
|
|
|
|
|
32552
|
|
860
|
25
|
50
|
66
|
|
|
130
|
Carp::carp "Odd (wrong?) number of parameters in new()" if $^W && (@_ & 1); |
861
|
25
|
0
|
|
|
|
100
|
while (@_) { my $method = shift; $self->$method(shift) if $self->can($method) } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
862
|
|
|
|
|
|
|
|
863
|
25
|
|
|
|
|
142
|
return $self; |
864
|
|
|
|
|
|
|
} |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
sub typelookup { |
867
|
25
|
|
|
25
|
|
56
|
my ($self, $lookup) = @_; |
868
|
25
|
50
|
|
|
|
101
|
if (defined $lookup) { |
869
|
25
|
|
|
|
|
219
|
$self->{ _typelookup } = $lookup; |
870
|
25
|
|
|
|
|
47
|
$self->{ _typelookup_order } = [ sort { $lookup->{$a}->[0] <=> $lookup->{$b}->[0] } keys %{ $lookup } ]; |
|
1285
|
|
|
|
|
1618
|
|
|
25
|
|
|
|
|
214
|
|
871
|
25
|
|
|
|
|
80
|
return $self; |
872
|
|
|
|
|
|
|
} |
873
|
0
|
|
|
|
|
0
|
return $self->{ _typelookup }; |
874
|
|
|
|
|
|
|
} |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
sub ns { |
877
|
3
|
|
|
3
|
|
352
|
my $self = shift; |
878
|
3
|
100
|
|
|
|
14
|
$self = $self->new() if not ref $self; |
879
|
3
|
50
|
|
|
|
9
|
if (@_) { |
880
|
3
|
|
|
|
|
6
|
my ($u,$p) = @_; |
881
|
3
|
|
|
|
|
3
|
my $prefix; |
882
|
|
|
|
|
|
|
|
883
|
3
|
100
|
33
|
|
|
17
|
if ($p) { |
|
|
50
|
|
|
|
|
|
884
|
1
|
|
|
|
|
6
|
$prefix = $p; |
885
|
|
|
|
|
|
|
} |
886
|
|
|
|
|
|
|
elsif (!$p && !($prefix = $self->find_prefix($u))) { |
887
|
2
|
|
|
|
|
11
|
$prefix = gen_ns; |
888
|
|
|
|
|
|
|
} |
889
|
|
|
|
|
|
|
|
890
|
3
|
|
|
|
|
7
|
$self->{'_ns_uri'} = $u; |
891
|
3
|
|
|
|
|
6
|
$self->{'_ns_prefix'} = $prefix; |
892
|
3
|
|
|
|
|
4
|
$self->{'_use_default_ns'} = 0; |
893
|
|
|
|
|
|
|
# $self->register_ns($u,$prefix); |
894
|
3
|
|
|
|
|
6
|
$self->{'_namespaces'}->{$u} = $prefix; |
895
|
3
|
|
|
|
|
13
|
return $self; |
896
|
|
|
|
|
|
|
} |
897
|
0
|
|
|
|
|
0
|
return $self->{'_ns_uri'}; |
898
|
|
|
|
|
|
|
} |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
sub default_ns { |
901
|
14
|
|
|
14
|
|
26
|
my $self = shift; |
902
|
14
|
100
|
|
|
|
131
|
$self = $self->new() if not ref $self; |
903
|
14
|
50
|
|
|
|
45
|
if (@_) { |
904
|
14
|
|
|
|
|
30
|
my ($u) = @_; |
905
|
14
|
|
|
|
|
43
|
$self->{'_ns_uri'} = $u; |
906
|
14
|
|
|
|
|
34
|
$self->{'_ns_prefix'} = ''; |
907
|
14
|
|
|
|
|
25
|
$self->{'_use_default_ns'} = 1; |
908
|
14
|
|
|
|
|
37
|
return $self; |
909
|
|
|
|
|
|
|
} |
910
|
0
|
|
|
|
|
0
|
return $self->{'_ns_uri'}; |
911
|
|
|
|
|
|
|
} |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
sub use_prefix { |
914
|
2
|
|
|
2
|
|
705
|
my $self = shift; |
915
|
2
|
50
|
|
|
|
13
|
$self = $self->new() if not ref $self; |
916
|
2
|
|
|
|
|
17
|
warn 'use_prefix has been deprecated. if you wish to turn off or on the ' |
917
|
|
|
|
|
|
|
. 'use of a default namespace, then please use either ns(uri) or default_ns(uri)'; |
918
|
2
|
50
|
|
|
|
9
|
if (@_) { |
919
|
2
|
|
|
|
|
3
|
my $use = shift; |
920
|
2
|
|
100
|
|
|
9
|
$self->{'_use_default_ns'} = !$use || 0; |
921
|
2
|
|
|
|
|
7
|
return $self; |
922
|
|
|
|
|
|
|
} else { |
923
|
0
|
|
|
|
|
0
|
return $self->{'_use_default_ns'}; |
924
|
|
|
|
|
|
|
} |
925
|
|
|
|
|
|
|
} |
926
|
|
|
|
|
|
|
sub uri { |
927
|
26
|
|
|
26
|
|
50
|
my $self = shift; |
928
|
26
|
50
|
|
|
|
94
|
$self = $self->new() if not ref $self; |
929
|
|
|
|
|
|
|
# warn 'uri has been deprecated. if you wish to set the namespace for the request, then please use either ns(uri) or default_ns(uri)'; |
930
|
26
|
100
|
|
|
|
89
|
if (@_) { |
931
|
14
|
|
|
|
|
27
|
my $ns = shift; |
932
|
14
|
100
|
|
|
|
60
|
if ($self->{_use_default_ns}) { |
933
|
13
|
|
|
|
|
53
|
$self->default_ns($ns); |
934
|
|
|
|
|
|
|
} |
935
|
|
|
|
|
|
|
else { |
936
|
1
|
|
|
|
|
4
|
$self->ns($ns); |
937
|
|
|
|
|
|
|
} |
938
|
|
|
|
|
|
|
# $self->{'_ns_uri'} = $ns; |
939
|
|
|
|
|
|
|
# $self->register_ns($self->{'_ns_uri'}) if (!$self->{_use_default_ns}); |
940
|
14
|
|
|
|
|
81
|
return $self; |
941
|
|
|
|
|
|
|
} |
942
|
12
|
|
|
|
|
50
|
return $self->{'_ns_uri'}; |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
sub encodingStyle { |
946
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
947
|
1
|
50
|
|
|
|
5
|
$self = $self->new() if not ref $self; |
948
|
1
|
50
|
|
|
|
39
|
return $self->{'_encodingStyle'} unless @_; |
949
|
|
|
|
|
|
|
|
950
|
0
|
|
|
|
|
0
|
my $cur_style = $self->{'_encodingStyle'}; |
951
|
0
|
|
|
|
|
0
|
delete($self->{'_namespaces'}->{$cur_style}); |
952
|
|
|
|
|
|
|
|
953
|
0
|
|
|
|
|
0
|
my $new_style = shift; |
954
|
0
|
0
|
|
|
|
0
|
if ($new_style eq "") { |
955
|
0
|
|
|
|
|
0
|
delete($self->{'_attr'}->{"{$SOAP::Constants::NS_ENV}encodingStyle"}); |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
else { |
958
|
0
|
|
|
|
|
0
|
$self->{'_attr'}->{"{$SOAP::Constants::NS_ENV}encodingStyle"} = $new_style; |
959
|
0
|
|
|
|
|
0
|
$self->{'_namespaces'}->{$new_style} = $SOAP::Constants::PREFIX_ENC; |
960
|
|
|
|
|
|
|
} |
961
|
|
|
|
|
|
|
} |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
# TODO - changing SOAP version can affect previously set encodingStyle |
964
|
|
|
|
|
|
|
sub soapversion { |
965
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
966
|
1
|
50
|
|
|
|
4
|
return $self->{_soapversion} unless @_; |
967
|
1
|
50
|
|
|
|
7
|
return $self if $self->{_soapversion} eq SOAP::Lite->soapversion; |
968
|
0
|
|
|
|
|
0
|
$self->{_soapversion} = shift; |
969
|
|
|
|
|
|
|
|
970
|
0
|
|
|
|
|
0
|
$self->attr({ |
971
|
|
|
|
|
|
|
"{$SOAP::Constants::NS_ENV}encodingStyle" => $SOAP::Constants::NS_ENC, |
972
|
|
|
|
|
|
|
}); |
973
|
0
|
0
|
|
|
|
0
|
$self->namespaces({ |
974
|
|
|
|
|
|
|
$SOAP::Constants::NS_ENC => $SOAP::Constants::PREFIX_ENC, |
975
|
|
|
|
|
|
|
$SOAP::Constants::PREFIX_ENV ? ($SOAP::Constants::NS_ENV => $SOAP::Constants::PREFIX_ENV) : (), |
976
|
|
|
|
|
|
|
}); |
977
|
0
|
|
|
|
|
0
|
$self->xmlschema($SOAP::Constants::DEFAULT_XML_SCHEMA); |
978
|
|
|
|
|
|
|
|
979
|
0
|
|
|
|
|
0
|
return $self; |
980
|
|
|
|
|
|
|
} |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
sub xmlschema { |
983
|
25
|
|
|
25
|
|
68
|
my $self = shift->new; |
984
|
25
|
50
|
|
|
|
101
|
return $self->{_xmlschema} unless @_; |
985
|
|
|
|
|
|
|
|
986
|
25
|
|
|
|
|
42
|
my @schema; |
987
|
25
|
50
|
|
|
|
102
|
if ($_[0]) { |
988
|
25
|
100
|
|
|
|
102
|
@schema = grep {/XMLSchema/ && /$_[0]/} keys %SOAP::Constants::XML_SCHEMAS; |
|
100
|
|
|
|
|
990
|
|
989
|
25
|
50
|
|
|
|
115
|
Carp::croak "More than one schema match parameter '$_[0]': @{[join ', ', @schema]}" if @schema > 1; |
|
0
|
|
|
|
|
0
|
|
990
|
25
|
50
|
|
|
|
86
|
Carp::croak "No schema match parameter '$_[0]'" if @schema != 1; |
991
|
|
|
|
|
|
|
} |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
# do nothing if current schema is the same as new |
994
|
|
|
|
|
|
|
# return $self if $self->{_xmlschema} && $self->{_xmlschema} eq $schema[0]; |
995
|
|
|
|
|
|
|
|
996
|
25
|
|
|
|
|
138
|
my $ns = $self->namespaces; |
997
|
|
|
|
|
|
|
# delete current schema from namespaces |
998
|
25
|
50
|
|
|
|
94
|
if (my $schema = $self->{_xmlschema}) { |
999
|
0
|
|
|
|
|
0
|
delete $ns->{$schema}; |
1000
|
0
|
|
|
|
|
0
|
delete $ns->{"$schema-instance"}; |
1001
|
|
|
|
|
|
|
} |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
# add new schema into namespaces |
1004
|
25
|
50
|
|
|
|
108
|
if (my $schema = $self->{_xmlschema} = shift @schema) { |
1005
|
25
|
|
|
|
|
58
|
$ns->{$schema} = 'xsd'; |
1006
|
25
|
|
|
|
|
106
|
$ns->{"$schema-instance"} = 'xsi'; |
1007
|
|
|
|
|
|
|
} |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
# and here is the class serializer should work with |
1010
|
25
|
50
|
|
|
|
157
|
my $class = exists $SOAP::Constants::XML_SCHEMAS{$self->{_xmlschema}} |
1011
|
|
|
|
|
|
|
? $SOAP::Constants::XML_SCHEMAS{$self->{_xmlschema}} . '::Serializer' |
1012
|
|
|
|
|
|
|
: $self; |
1013
|
|
|
|
|
|
|
|
1014
|
25
|
|
|
|
|
190
|
$self->xmlschemaclass($class); |
1015
|
|
|
|
|
|
|
|
1016
|
25
|
|
|
|
|
48
|
return $self; |
1017
|
|
|
|
|
|
|
} |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
sub envprefix { |
1020
|
42
|
|
|
42
|
|
103
|
my $self = shift->new(); |
1021
|
42
|
50
|
|
|
|
179
|
return $self->namespaces->{$SOAP::Constants::NS_ENV} unless @_; |
1022
|
0
|
|
|
|
|
0
|
$self->namespaces->{$SOAP::Constants::NS_ENV} = shift; |
1023
|
0
|
|
|
|
|
0
|
return $self; |
1024
|
|
|
|
|
|
|
} |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
sub encprefix { |
1027
|
3
|
|
|
3
|
|
14
|
my $self = shift->new(); |
1028
|
3
|
50
|
|
|
|
13
|
return $self->namespaces->{$SOAP::Constants::NS_ENC} unless @_; |
1029
|
0
|
|
|
|
|
0
|
$self->namespaces->{$SOAP::Constants::NS_ENC} = shift; |
1030
|
0
|
|
|
|
|
0
|
return $self; |
1031
|
|
|
|
|
|
|
} |
1032
|
|
|
|
|
|
|
|
1033
|
204
|
|
|
204
|
|
1089
|
sub gen_id { sprintf "%U", $_[1] } |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
sub multiref_object { |
1036
|
152
|
|
|
152
|
|
180
|
my ($self, $object) = @_; |
1037
|
152
|
|
|
|
|
453
|
my $id = $self->gen_id($object); |
1038
|
152
|
100
|
|
|
|
416
|
if (! exists $self->{ _seen }->{ $id }) { |
1039
|
150
|
|
|
|
|
716
|
$self->{ _seen }->{ $id } = { |
1040
|
|
|
|
|
|
|
count => 1, |
1041
|
|
|
|
|
|
|
multiref => 0, |
1042
|
|
|
|
|
|
|
value => $object, |
1043
|
|
|
|
|
|
|
recursive => 0 |
1044
|
|
|
|
|
|
|
}; |
1045
|
|
|
|
|
|
|
} |
1046
|
|
|
|
|
|
|
else { |
1047
|
2
|
|
|
|
|
4
|
my $id_seen = $self->{ _seen }->{ $id }; |
1048
|
2
|
|
|
|
|
5
|
$id_seen->{count}++; |
1049
|
2
|
|
|
|
|
4
|
$id_seen->{multiref} = 1; |
1050
|
2
|
|
|
|
|
4
|
$id_seen->{value} = $object; |
1051
|
2
|
|
100
|
|
|
22
|
$id_seen->{recursive} ||= 0; |
1052
|
|
|
|
|
|
|
} |
1053
|
152
|
|
|
|
|
288
|
return $id; |
1054
|
|
|
|
|
|
|
} |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
sub recursive_object { |
1057
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1058
|
0
|
|
|
|
|
0
|
$self->seen->{$self->gen_id(shift)}->{recursive} = 1; |
1059
|
|
|
|
|
|
|
} |
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
sub is_href { |
1062
|
52
|
|
|
52
|
|
64
|
my $self = shift; |
1063
|
52
|
50
|
50
|
|
|
134
|
my $seen = $self->seen->{shift || return} or return; |
1064
|
52
|
100
|
|
|
|
128
|
return 1 if $seen->{id}; |
1065
|
51
|
|
66
|
|
|
234
|
return $seen->{multiref} |
1066
|
|
|
|
|
|
|
&& !($seen->{id} = (shift |
1067
|
|
|
|
|
|
|
|| $seen->{recursive} |
1068
|
|
|
|
|
|
|
|| $seen->{multiref} && $self->multirefinplace)); |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
sub multiref_anchor { |
1072
|
2
|
|
|
2
|
|
5
|
my ($self, $id) = @_; |
1073
|
25
|
|
|
25
|
|
167
|
no warnings qw(uninitialized); |
|
25
|
|
|
|
|
43
|
|
|
25
|
|
|
|
|
9764
|
|
1074
|
2
|
50
|
|
|
|
7
|
if ($self->{ _seen }->{ $id }->{multiref}) { |
1075
|
2
|
|
|
|
|
14
|
return "ref-$id" |
1076
|
|
|
|
|
|
|
} |
1077
|
|
|
|
|
|
|
else { |
1078
|
0
|
|
|
|
|
0
|
return undef; |
1079
|
|
|
|
|
|
|
} |
1080
|
|
|
|
|
|
|
} |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
sub encode_multirefs { |
1083
|
21
|
|
|
21
|
|
35
|
my $self = shift; |
1084
|
21
|
50
|
|
|
|
83
|
return if $self->multirefinplace(); |
1085
|
|
|
|
|
|
|
|
1086
|
21
|
|
|
|
|
52
|
my $seen = $self->{ _seen }; |
1087
|
0
|
|
|
|
|
0
|
map { $_->[1]->{_id} = 1; $_ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1088
|
149
|
100
|
|
|
|
351
|
map { $self->encode_object($seen->{$_}->{value}) } |
1089
|
21
|
|
|
|
|
120
|
grep { $seen->{$_}->{multiref} && !$seen->{$_}->{recursive} } |
1090
|
|
|
|
|
|
|
keys %$seen; |
1091
|
|
|
|
|
|
|
} |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
sub maptypetouri { |
1094
|
52
|
|
|
52
|
|
76
|
my($self, $type, $simple) = @_; |
1095
|
|
|
|
|
|
|
|
1096
|
52
|
100
|
|
|
|
576
|
return $type unless defined $type; |
1097
|
1
|
|
|
|
|
3
|
my($prefix, $name) = SOAP::Utils::splitqname($type); |
1098
|
|
|
|
|
|
|
|
1099
|
1
|
50
|
|
|
|
6
|
unless (defined $prefix) { |
1100
|
0
|
|
|
|
|
0
|
$name =~ s/__|\./::/g; |
1101
|
0
|
0
|
|
|
|
0
|
$self->maptype->{$name} = $simple |
|
|
0
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
? die "Schema/namespace for type '$type' is not specified\n" |
1103
|
|
|
|
|
|
|
: $SOAP::Constants::NS_SL_PERLTYPE |
1104
|
|
|
|
|
|
|
unless exists $self->maptype->{$name}; |
1105
|
0
|
0
|
0
|
|
|
0
|
$type = $self->maptype->{$name} |
1106
|
|
|
|
|
|
|
? SOAP::Utils::qualify($self->namespaces->{$self->maptype->{$name}} ||= gen_ns, $type) |
1107
|
|
|
|
|
|
|
: undef; |
1108
|
|
|
|
|
|
|
} |
1109
|
1
|
|
|
|
|
8
|
return $type; |
1110
|
|
|
|
|
|
|
} |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
sub encode_object { |
1113
|
176
|
|
|
176
|
|
288
|
my($self, $object, $name, $type, $attr) = @_; |
1114
|
|
|
|
|
|
|
|
1115
|
176
|
|
100
|
|
|
495
|
$attr ||= {}; |
1116
|
176
|
100
|
|
|
|
597
|
return $self->encode_scalar($object, $name, $type, $attr) |
1117
|
|
|
|
|
|
|
unless ref $object; |
1118
|
|
|
|
|
|
|
|
1119
|
152
|
|
|
|
|
308
|
my $id = $self->multiref_object($object); |
1120
|
|
|
|
|
|
|
|
1121
|
25
|
|
|
25
|
|
133
|
use vars '%objectstack'; # we'll play with symbol table |
|
25
|
|
|
|
|
42
|
|
|
25
|
|
|
|
|
4398
|
|
1122
|
152
|
|
|
|
|
630
|
local %objectstack = %objectstack; # want to see objects ONLY in the current tree |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
# did we see this object in current tree? Seems to be recursive refs |
1125
|
|
|
|
|
|
|
# same as call to $self->recursive_object($object) - but |
1126
|
|
|
|
|
|
|
# recursive_object($object) has to re-compute the object's id |
1127
|
152
|
100
|
|
|
|
468
|
if (++$objectstack{ $id } > 1) { |
1128
|
2
|
|
|
|
|
6
|
$self->{ _seen }->{ $id }->{recursive} = 1 |
1129
|
|
|
|
|
|
|
} |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
# return if we already saw it twice. It should be already properly serialized |
1132
|
152
|
100
|
|
|
|
348
|
return if $objectstack{$id} > 2; |
1133
|
|
|
|
|
|
|
|
1134
|
151
|
100
|
|
|
|
479
|
if (UNIVERSAL::isa($object => 'SOAP::Data')) { |
1135
|
|
|
|
|
|
|
# use $object->SOAP::Data:: to enable overriding name() and others in inherited classes |
1136
|
99
|
100
|
|
|
|
319
|
$object->SOAP::Data::name($name) |
1137
|
|
|
|
|
|
|
unless defined $object->SOAP::Data::name; |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
# apply ->uri() and ->prefix() which can modify name and attributes of |
1140
|
|
|
|
|
|
|
# element, but do not modify SOAP::Data itself |
1141
|
99
|
|
|
|
|
253
|
my($name, $attr) = $self->fixattrs($object); |
1142
|
99
|
|
|
|
|
265
|
$attr = $self->attrstoqname($attr); |
1143
|
|
|
|
|
|
|
|
1144
|
99
|
|
|
|
|
436
|
my @realvalues = $object->SOAP::Data::value; |
1145
|
99
|
50
|
0
|
|
|
243
|
return [$name || gen_name, $attr] unless @realvalues; |
1146
|
|
|
|
|
|
|
|
1147
|
99
|
|
50
|
|
|
1244
|
my $method = "as_" . ($object->SOAP::Data::type || '-'); # dummy type if not defined |
1148
|
|
|
|
|
|
|
# try to call method specified for this type |
1149
|
25
|
|
|
25
|
|
129
|
no strict qw(refs); |
|
25
|
|
|
|
|
42
|
|
|
25
|
|
|
|
|
6524
|
|
1150
|
106
|
100
|
|
|
|
250
|
my @values = map { |
1151
|
|
|
|
|
|
|
# store null/nil attribute if value is undef |
1152
|
99
|
|
|
|
|
157
|
local $attr->{SOAP::Utils::qualify(xsi => $self->xmlschemaclass->nilValue)} = $self->xmlschemaclass->as_undef(1) |
1153
|
|
|
|
|
|
|
unless defined; |
1154
|
106
|
100
|
0
|
|
|
1066
|
$self->can($method) && $self->$method($_, $name || gen_name, $object->SOAP::Data::type, $attr) |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1155
|
|
|
|
|
|
|
|| $self->typecast($_, $name || gen_name, $object->SOAP::Data::type, $attr) |
1156
|
|
|
|
|
|
|
|| $self->encode_object($_, $name, $object->SOAP::Data::type, $attr) |
1157
|
|
|
|
|
|
|
} @realvalues; |
1158
|
99
|
50
|
100
|
|
|
266
|
$object->SOAP::Data::signature([map {join $;, $_->[0], SOAP::Utils::disqualify($_->[1]->{'xsi:type'} || '')} @values]) if @values; |
|
106
|
|
|
|
|
524
|
|
1159
|
99
|
50
|
|
|
|
587
|
return wantarray ? @values : $values[0]; |
1160
|
|
|
|
|
|
|
} |
1161
|
|
|
|
|
|
|
|
1162
|
52
|
|
|
|
|
91
|
my $class = ref $object; |
1163
|
|
|
|
|
|
|
|
1164
|
52
|
50
|
|
|
|
351
|
if ($class !~ /^(?:SCALAR|ARRAY|HASH|REF)$/o) { |
1165
|
|
|
|
|
|
|
# we could also check for CODE|GLOB|LVALUE, but we cannot serialize |
1166
|
|
|
|
|
|
|
# them anyway, so they'll be caught by check below |
1167
|
0
|
|
|
|
|
0
|
$class =~ s/::/__/g; |
1168
|
|
|
|
|
|
|
|
1169
|
0
|
0
|
|
|
|
0
|
$name = $class if !defined $name; |
1170
|
0
|
0
|
0
|
|
|
0
|
$type = $class if !defined $type && $self->autotype; |
1171
|
|
|
|
|
|
|
|
1172
|
0
|
|
|
|
|
0
|
my $method = 'as_' . $class; |
1173
|
0
|
0
|
|
|
|
0
|
if ($self->can($method)) { |
1174
|
25
|
|
|
25
|
|
136
|
no strict qw(refs); |
|
25
|
|
|
|
|
47
|
|
|
25
|
|
|
|
|
7676
|
|
1175
|
0
|
|
|
|
|
0
|
my $encoded = $self->$method($object, $name, $type, $attr); |
1176
|
0
|
0
|
|
|
|
0
|
return $encoded if ref $encoded; |
1177
|
|
|
|
|
|
|
# return only if handled, otherwise handle with default handlers |
1178
|
|
|
|
|
|
|
} |
1179
|
|
|
|
|
|
|
} |
1180
|
|
|
|
|
|
|
|
1181
|
52
|
100
|
100
|
|
|
227
|
if (UNIVERSAL::isa($object => 'REF') || UNIVERSAL::isa($object => 'SCALAR')) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1182
|
50
|
|
|
|
|
256
|
return $self->encode_scalar($object, $name, $type, $attr); |
1183
|
|
|
|
|
|
|
} |
1184
|
|
|
|
|
|
|
elsif (UNIVERSAL::isa($object => 'ARRAY')) { |
1185
|
|
|
|
|
|
|
# Added in SOAP::Lite 0.65_6 to fix an XMLRPC bug |
1186
|
1
|
50
|
33
|
|
|
6
|
return $self->encodingStyle eq "" |
1187
|
|
|
|
|
|
|
|| $self->isa('XMLRPC::Serializer') |
1188
|
|
|
|
|
|
|
? $self->encode_array($object, $name, $type, $attr) |
1189
|
|
|
|
|
|
|
: $self->encode_literal_array($object, $name, $type, $attr); |
1190
|
|
|
|
|
|
|
} |
1191
|
|
|
|
|
|
|
elsif (UNIVERSAL::isa($object => 'HASH')) { |
1192
|
1
|
|
|
|
|
5
|
return $self->encode_hash($object, $name, $type, $attr); |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
else { |
1195
|
0
|
|
|
|
|
0
|
return $self->on_nonserialized->($object); |
1196
|
|
|
|
|
|
|
} |
1197
|
|
|
|
|
|
|
} |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
sub encode_scalar { |
1200
|
89
|
|
|
89
|
|
903
|
my($self, $value, $name, $type, $attr) = @_; |
1201
|
89
|
|
66
|
|
|
177
|
$name ||= gen_name; |
1202
|
|
|
|
|
|
|
|
1203
|
89
|
|
|
|
|
273
|
my $schemaclass = $self->xmlschemaclass; |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
# null reference |
1206
|
89
|
100
|
|
|
|
281
|
return [$name, {%$attr, SOAP::Utils::qualify(xsi => $schemaclass->nilValue) => $schemaclass->as_undef(1)}] unless defined $value; |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
# object reference |
1209
|
78
|
100
|
|
|
|
291
|
return [$name, {'xsi:type' => $self->maptypetouri($type), %$attr}, [$self->encode_object($$value)], $self->gen_id($value)] if ref $value; |
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
# autodefined type |
1212
|
28
|
50
|
|
|
|
72
|
if ($self->{ _autotype}) { |
1213
|
28
|
|
|
|
|
45
|
my $lookup = $self->{_typelookup}; |
1214
|
25
|
|
|
25
|
|
144
|
no strict qw(refs); |
|
25
|
|
|
|
|
46
|
|
|
25
|
|
|
|
|
91010
|
|
1215
|
|
|
|
|
|
|
#for (sort {$lookup->{$a}->[0] <=> $lookup->{$b}->[0]} keys %$lookup) { |
1216
|
28
|
|
|
|
|
31
|
for (@{ $self->{ _typelookup_order } }) { |
|
28
|
|
|
|
|
78
|
|
1217
|
217
|
|
|
|
|
329
|
my $method = $lookup->{$_}->[2]; |
1218
|
217
|
100
|
33
|
|
|
428
|
return $self->can($method) && $self->$method($value, $name, $type, $attr) |
1219
|
|
|
|
|
|
|
|| $method->($value, $name, $type, $attr) |
1220
|
|
|
|
|
|
|
if $lookup->{$_}->[1]->($value); |
1221
|
|
|
|
|
|
|
} |
1222
|
|
|
|
|
|
|
} |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
# invariant |
1225
|
0
|
|
|
|
|
0
|
return [$name, $attr, $value]; |
1226
|
|
|
|
|
|
|
} |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
sub encode_array { |
1229
|
0
|
|
|
0
|
|
0
|
my ($self, $array, $name, $type, $attr) = @_; |
1230
|
0
|
|
|
|
|
0
|
my $items = 'item'; |
1231
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
# If typing is disabled, just serialize each of the array items |
1233
|
|
|
|
|
|
|
# with no type information, each using the specified name, |
1234
|
|
|
|
|
|
|
# and do not create a wrapper array tag. |
1235
|
0
|
0
|
|
|
|
0
|
if (!$self->autotype) { |
1236
|
0
|
|
0
|
|
|
0
|
$name ||= gen_name; |
1237
|
0
|
|
|
|
|
0
|
return map {$self->encode_object($_, $name)} @$array; |
|
0
|
|
|
|
|
0
|
|
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
# TODO: add support for multidimensional, partially transmitted and sparse arrays |
1241
|
0
|
|
|
|
|
0
|
my @items = map {$self->encode_object($_, $items)} @$array; |
|
0
|
|
|
|
|
0
|
|
1242
|
0
|
|
|
|
|
0
|
my $num = @items; |
1243
|
0
|
|
|
|
|
0
|
my($arraytype, %types) = '-'; |
1244
|
0
|
|
0
|
|
|
0
|
for (@items) { $arraytype = $_->[1]->{'xsi:type'} || '-'; $types{$arraytype}++ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1245
|
0
|
0
|
0
|
|
|
0
|
$arraytype = sprintf "%s\[$num]", keys %types > 1 || $arraytype eq '-' ? SOAP::Utils::qualify(xsd => $self->xmlschemaclass->anyTypeValue) : $arraytype; |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
# $type = SOAP::Utils::qualify($self->encprefix => 'Array') if $self->autotype && !defined $type; |
1248
|
0
|
0
|
|
|
|
0
|
$type = qualify($self->encprefix => 'Array') if !defined $type; |
1249
|
0
|
|
0
|
|
|
0
|
return [$name || SOAP::Utils::qualify($self->encprefix => 'Array'), |
1250
|
|
|
|
|
|
|
{ |
1251
|
|
|
|
|
|
|
SOAP::Utils::qualify($self->encprefix => 'arrayType') => $arraytype, |
1252
|
|
|
|
|
|
|
'xsi:type' => $self->maptypetouri($type), %$attr |
1253
|
|
|
|
|
|
|
}, |
1254
|
|
|
|
|
|
|
[@items], |
1255
|
|
|
|
|
|
|
$self->gen_id($array) |
1256
|
|
|
|
|
|
|
]; |
1257
|
|
|
|
|
|
|
} |
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
# Will encode arrays using doc-literal style |
1260
|
|
|
|
|
|
|
sub encode_literal_array { |
1261
|
1
|
|
|
1
|
|
4
|
my($self, $array, $name, $type, $attr) = @_; |
1262
|
|
|
|
|
|
|
|
1263
|
1
|
50
|
|
|
|
5
|
if ($self->autotype) { |
1264
|
1
|
|
|
|
|
3
|
my $items = 'item'; |
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
# TODO: add support for multidimensional, partially transmitted and sparse arrays |
1267
|
1
|
|
|
|
|
3
|
my @items = map {$self->encode_object($_, $items)} @$array; |
|
2
|
|
|
|
|
5
|
|
1268
|
|
|
|
|
|
|
|
1269
|
|
|
|
|
|
|
|
1270
|
1
|
|
|
|
|
3
|
my $num = @items; |
1271
|
1
|
|
|
|
|
4
|
my($arraytype, %types) = '-'; |
1272
|
1
|
|
|
|
|
3
|
for (@items) { |
1273
|
2
|
|
50
|
|
|
7
|
$arraytype = $_->[1]->{'xsi:type'} || '-'; |
1274
|
2
|
|
|
|
|
7
|
$types{$arraytype}++ |
1275
|
|
|
|
|
|
|
} |
1276
|
1
|
50
|
33
|
|
|
14
|
$arraytype = sprintf "%s\[$num]", keys %types > 1 || $arraytype eq '-' |
1277
|
|
|
|
|
|
|
? SOAP::Utils::qualify(xsd => $self->xmlschemaclass->anyTypeValue) |
1278
|
|
|
|
|
|
|
: $arraytype; |
1279
|
|
|
|
|
|
|
|
1280
|
1
|
50
|
|
|
|
8
|
$type = SOAP::Utils::qualify($self->encprefix => 'Array') |
1281
|
|
|
|
|
|
|
if !defined $type; |
1282
|
|
|
|
|
|
|
|
1283
|
1
|
|
33
|
|
|
7
|
return [$name || SOAP::Utils::qualify($self->encprefix => 'Array'), |
1284
|
|
|
|
|
|
|
{ |
1285
|
|
|
|
|
|
|
SOAP::Utils::qualify($self->encprefix => 'arrayType') => $arraytype, |
1286
|
|
|
|
|
|
|
'xsi:type' => $self->maptypetouri($type), %$attr |
1287
|
|
|
|
|
|
|
}, |
1288
|
|
|
|
|
|
|
[ @items ], |
1289
|
|
|
|
|
|
|
$self->gen_id($array) |
1290
|
|
|
|
|
|
|
]; |
1291
|
|
|
|
|
|
|
} |
1292
|
|
|
|
|
|
|
else { |
1293
|
|
|
|
|
|
|
# |
1294
|
|
|
|
|
|
|
# literal arrays are different - { array => [ 5,6 ] } |
1295
|
|
|
|
|
|
|
# results in 56 |
1296
|
|
|
|
|
|
|
# This means that if there's a literal inside the array (not a |
1297
|
|
|
|
|
|
|
# reference), we have to encode it this way. If there's only |
1298
|
|
|
|
|
|
|
# nested tags, encode as |
1299
|
|
|
|
|
|
|
# 12 |
1300
|
|
|
|
|
|
|
# |
1301
|
|
|
|
|
|
|
|
1302
|
0
|
|
|
|
|
0
|
my $literal = undef; |
1303
|
|
|
|
|
|
|
my @items = map { |
1304
|
0
|
|
|
|
|
0
|
ref $_ |
1305
|
|
|
|
|
|
|
? $self->encode_object($_) |
1306
|
0
|
0
|
|
|
|
0
|
: do { |
1307
|
0
|
|
|
|
|
0
|
$literal++; |
1308
|
0
|
|
|
|
|
0
|
$_ |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
} @$array; |
1312
|
|
|
|
|
|
|
|
1313
|
0
|
0
|
|
|
|
0
|
if ($literal) { |
1314
|
0
|
|
|
|
|
0
|
return map { [ $name , $attr , $_, $self->gen_id($array) ] } @items; |
|
0
|
|
|
|
|
0
|
|
1315
|
|
|
|
|
|
|
} |
1316
|
|
|
|
|
|
|
else { |
1317
|
0
|
|
0
|
|
|
0
|
return [$name || SOAP::Utils::qualify($self->encprefix => 'Array'), |
1318
|
|
|
|
|
|
|
$attr, |
1319
|
|
|
|
|
|
|
[ @items ], |
1320
|
|
|
|
|
|
|
$self->gen_id($array) |
1321
|
|
|
|
|
|
|
]; |
1322
|
|
|
|
|
|
|
} |
1323
|
|
|
|
|
|
|
} |
1324
|
|
|
|
|
|
|
} |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
sub encode_hash { |
1327
|
1
|
|
|
1
|
|
11
|
my($self, $hash, $name, $type, $attr) = @_; |
1328
|
|
|
|
|
|
|
|
1329
|
1
|
50
|
33
|
|
|
6
|
if ($self->autotype && grep {!/$SOAP::Constants::ELMASK/o} keys %$hash) { |
|
1
|
|
|
|
|
109
|
|
1330
|
0
|
0
|
|
|
|
0
|
warn qq!Cannot encode @{[$name ? "'$name'" : 'unnamed']} element as 'hash'. Will be encoded as 'map' instead\n! if $^W; |
|
0
|
0
|
|
|
|
0
|
|
1331
|
0
|
|
0
|
|
|
0
|
return $self->as_map($hash, $name || gen_name, $type, $attr); |
1332
|
|
|
|
|
|
|
} |
1333
|
|
|
|
|
|
|
|
1334
|
1
|
50
|
33
|
|
|
6
|
$type = 'SOAPStruct' |
|
|
|
33
|
|
|
|
|
1335
|
|
|
|
|
|
|
if $self->autotype && !defined($type) && exists $self->maptype->{SOAPStruct}; |
1336
|
1
|
|
|
|
|
4
|
return [$name || gen_name, |
1337
|
|
|
|
|
|
|
$self->autotype ? {'xsi:type' => $self->maptypetouri($type), %$attr} : { %$attr }, |
1338
|
1
|
50
|
33
|
|
|
8
|
[map {$self->encode_object($hash->{$_}, $_)} keys %$hash], |
1339
|
|
|
|
|
|
|
$self->gen_id($hash) |
1340
|
|
|
|
|
|
|
]; |
1341
|
|
|
|
|
|
|
} |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
sub as_ordered_hash { |
1344
|
0
|
|
|
0
|
|
0
|
my ($self, $value, $name, $type, $attr) = @_; |
1345
|
0
|
0
|
|
|
|
0
|
die "Not an ARRAY reference for 'ordered_hash' type" unless UNIVERSAL::isa($value => 'ARRAY'); |
1346
|
0
|
|
|
|
|
0
|
return [ $name, $attr, |
1347
|
0
|
|
|
|
|
0
|
[map{$self->encode_object(@{$value}[2*$_+1,2*$_])} 0..$#$value/2 ], |
|
0
|
|
|
|
|
0
|
|
1348
|
|
|
|
|
|
|
$self->gen_id($value) |
1349
|
|
|
|
|
|
|
]; |
1350
|
|
|
|
|
|
|
} |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
sub as_map { |
1353
|
0
|
|
|
0
|
|
0
|
my ($self, $value, $name, $type, $attr) = @_; |
1354
|
0
|
0
|
|
|
|
0
|
die "Not a HASH reference for 'map' type" unless UNIVERSAL::isa($value => 'HASH'); |
1355
|
0
|
|
0
|
|
|
0
|
my $prefix = ($self->namespaces->{$SOAP::Constants::NS_APS} ||= 'apachens'); |
1356
|
0
|
|
|
|
|
0
|
my @items = map { |
1357
|
0
|
|
|
|
|
0
|
$self->encode_object( |
1358
|
|
|
|
|
|
|
SOAP::Data->type( |
1359
|
|
|
|
|
|
|
ordered_hash => [ |
1360
|
|
|
|
|
|
|
key => $_, |
1361
|
|
|
|
|
|
|
value => $value->{$_} |
1362
|
|
|
|
|
|
|
] |
1363
|
|
|
|
|
|
|
), |
1364
|
|
|
|
|
|
|
'item', |
1365
|
|
|
|
|
|
|
'' |
1366
|
|
|
|
|
|
|
)} sort keys %$value; |
1367
|
|
|
|
|
|
|
return [ |
1368
|
0
|
|
|
|
|
0
|
$name, |
1369
|
|
|
|
|
|
|
{'xsi:type' => "$prefix:Map", %$attr}, |
1370
|
|
|
|
|
|
|
[@items], |
1371
|
|
|
|
|
|
|
$self->gen_id($value) |
1372
|
|
|
|
|
|
|
]; |
1373
|
|
|
|
|
|
|
} |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
sub as_xml { |
1376
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1377
|
0
|
|
|
|
|
0
|
my($value, $name, $type, $attr) = @_; |
1378
|
0
|
|
|
|
|
0
|
return [$name, {'_xml' => 1}, $value]; |
1379
|
|
|
|
|
|
|
} |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
sub typecast { |
1382
|
106
|
|
|
106
|
|
116
|
my $self = shift; |
1383
|
106
|
|
|
|
|
169
|
my($value, $name, $type, $attr) = @_; |
1384
|
106
|
100
|
|
|
|
607
|
return if ref $value; # skip complex object, caller knows how to deal with it |
1385
|
25
|
100
|
66
|
|
|
113
|
return if $self->autotype && !defined $type; # we don't know, autotype knows |
1386
|
5
|
50
|
33
|
|
|
67
|
return [$name, |
1387
|
|
|
|
|
|
|
{(defined $type && $type gt '' ? ('xsi:type' => $self->maptypetouri($type, 'simple type')) : ()), %$attr}, |
1388
|
|
|
|
|
|
|
$value |
1389
|
|
|
|
|
|
|
]; |
1390
|
|
|
|
|
|
|
} |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
sub register_ns { |
1393
|
68
|
|
|
68
|
|
217
|
my $self = shift->new(); |
1394
|
68
|
|
|
|
|
113
|
my ($ns,$prefix) = @_; |
1395
|
68
|
100
|
|
|
|
148
|
$prefix = gen_ns if !$prefix; |
1396
|
68
|
100
|
|
|
|
228
|
$self->{'_namespaces'}->{$ns} = $prefix if $ns; |
1397
|
|
|
|
|
|
|
} |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
sub find_prefix { |
1400
|
5
|
|
|
5
|
|
9
|
my ($self, $ns) = @_; |
1401
|
5
|
100
|
|
|
|
30
|
return (exists $self->{'_namespaces'}->{$ns}) |
1402
|
|
|
|
|
|
|
? $self->{'_namespaces'}->{$ns} |
1403
|
|
|
|
|
|
|
: (); |
1404
|
|
|
|
|
|
|
} |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
sub fixattrs { |
1407
|
99
|
|
|
99
|
|
134
|
my ($self, $data) = @_; |
1408
|
99
|
|
|
|
|
239
|
my ($name, $attr) = ($data->SOAP::Data::name, {%{$data->SOAP::Data::attr}}); |
|
99
|
|
|
|
|
231
|
|
1409
|
99
|
|
|
|
|
261
|
my ($xmlns, $prefix) = ($data->uri, $data->prefix); |
1410
|
99
|
100
|
66
|
|
|
494
|
unless (defined($xmlns) || defined($prefix)) { |
1411
|
56
|
100
|
|
|
|
172
|
$self->register_ns($xmlns,$prefix) unless ($self->use_default_ns); |
1412
|
56
|
|
|
|
|
138
|
return ($name, $attr); |
1413
|
|
|
|
|
|
|
} |
1414
|
43
|
|
33
|
|
|
106
|
$name ||= gen_name(); # local name |
1415
|
43
|
50
|
33
|
|
|
153
|
$prefix = gen_ns() if !defined $prefix && $xmlns gt ''; |
1416
|
43
|
50
|
33
|
|
|
403
|
$prefix = '' |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
1417
|
|
|
|
|
|
|
if defined $xmlns && $xmlns eq '' |
1418
|
|
|
|
|
|
|
|| defined $prefix && $prefix eq ''; |
1419
|
|
|
|
|
|
|
|
1420
|
43
|
50
|
0
|
|
|
88
|
$attr->{join ':', xmlns => $prefix || ()} = $xmlns if defined $xmlns; |
1421
|
43
|
50
|
|
|
|
163
|
$name = join ':', $prefix, $name if $prefix; |
1422
|
|
|
|
|
|
|
|
1423
|
43
|
100
|
|
|
|
150
|
$self->register_ns($xmlns,$prefix) unless ($self->use_default_ns); |
1424
|
|
|
|
|
|
|
|
1425
|
43
|
|
|
|
|
113
|
return ($name, $attr); |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
} |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
sub toqname { |
1430
|
21
|
|
|
21
|
|
36
|
my $self = shift; |
1431
|
21
|
|
|
|
|
295
|
my $long = shift; |
1432
|
|
|
|
|
|
|
|
1433
|
21
|
50
|
|
|
|
450
|
return $long unless $long =~ /^\{(.*)\}(.+)$/; |
1434
|
21
|
|
33
|
|
|
220
|
return SOAP::Utils::qualify $self->namespaces->{$1} ||= gen_ns, $2; |
1435
|
|
|
|
|
|
|
} |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
sub attrstoqname { |
1438
|
99
|
|
|
99
|
|
132
|
my $self = shift; |
1439
|
99
|
|
|
|
|
105
|
my $attrs = shift; |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
return { |
1442
|
99
|
50
|
33
|
|
|
279
|
map { /^\{(.*)\}(.+)$/ |
|
34
|
100
|
|
|
|
282
|
|
1443
|
|
|
|
|
|
|
? ($self->toqname($_) => $2 eq 'type' |
1444
|
|
|
|
|
|
|
|| $2 eq 'arrayType' |
1445
|
|
|
|
|
|
|
? $self->toqname($attrs->{$_}) |
1446
|
|
|
|
|
|
|
: $attrs->{$_}) |
1447
|
|
|
|
|
|
|
: ($_ => $attrs->{$_}) |
1448
|
|
|
|
|
|
|
} keys %$attrs |
1449
|
|
|
|
|
|
|
}; |
1450
|
|
|
|
|
|
|
} |
1451
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
sub tag { |
1453
|
81
|
|
|
81
|
|
244
|
my ($self, $tag, $attrs, @values) = @_; |
1454
|
|
|
|
|
|
|
|
1455
|
81
|
|
|
|
|
117
|
my $readable = $self->{ _readable }; |
1456
|
|
|
|
|
|
|
|
1457
|
81
|
|
|
|
|
148
|
my $value = join '', @values; |
1458
|
81
|
50
|
|
|
|
154
|
my $indent = $readable ? ' ' x (($self->{ _level }-1)*2) : ''; |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
# check for special attribute |
1461
|
81
|
50
|
33
|
|
|
229
|
return "$indent$value" if exists $attrs->{_xml} && delete $attrs->{_xml}; |
1462
|
|
|
|
|
|
|
|
1463
|
81
|
50
|
|
|
|
1090
|
die "Element '$tag' can't be allowed in valid XML message. Died." |
1464
|
|
|
|
|
|
|
if $tag !~ /^$SOAP::Constants::NSMASK$/o; |
1465
|
|
|
|
|
|
|
|
1466
|
81
|
50
|
|
|
|
243
|
warn "Element '$tag' uses the reserved prefix 'XML' (in any case)" |
1467
|
|
|
|
|
|
|
if $tag !~ /^(?![Xx][Mm][Ll])/; |
1468
|
|
|
|
|
|
|
|
1469
|
81
|
50
|
|
|
|
154
|
my $prolog = $readable ? "\n" : ""; |
1470
|
81
|
50
|
|
|
|
146
|
my $epilog = $readable ? "\n" : ""; |
1471
|
81
|
|
|
|
|
83
|
my $tagjoiner = " "; |
1472
|
81
|
100
|
|
|
|
251
|
if ($self->{ _level } == 1) { |
1473
|
22
|
|
|
|
|
96
|
my $namespaces = $self->namespaces; |
1474
|
22
|
|
|
|
|
101
|
foreach (keys %$namespaces) { |
1475
|
87
|
|
|
|
|
170
|
$attrs->{SOAP::Utils::qualify(xmlns => $namespaces->{$_})} = $_ |
1476
|
|
|
|
|
|
|
} |
1477
|
22
|
50
|
|
|
|
165
|
$prolog = qq!encoding]}"?>! |
|
22
|
|
|
|
|
70
|
|
1478
|
|
|
|
|
|
|
if defined $self->encoding; |
1479
|
22
|
50
|
|
|
|
77
|
$prolog .= "\n" if $readable; |
1480
|
22
|
50
|
|
|
|
65
|
$tagjoiner = " \n".(' ' x 4 ) if $readable; |
1481
|
|
|
|
|
|
|
} |
1482
|
149
|
|
|
|
|
299
|
my $tagattrs = join($tagjoiner, '', |
1483
|
200
|
100
|
66
|
|
|
1137
|
map { sprintf '%s="%s"', $_, SOAP::Utils::encode_attribute($attrs->{$_}) } |
|
|
|
66
|
|
|
|
|
1484
|
81
|
|
|
|
|
337
|
grep { $_ && defined $attrs->{$_} && ($_ ne 'xsi:type' || $attrs->{$_} ne '') } |
1485
|
|
|
|
|
|
|
sort keys %$attrs); |
1486
|
|
|
|
|
|
|
|
1487
|
81
|
100
|
|
|
|
211
|
if ($value gt '') { |
1488
|
69
|
100
|
|
|
|
962
|
return sprintf("$prolog$indent<%s%s>%s%s%s>$epilog",$tag,$tagattrs,$value,($value =~ /^\s* ? $indent : ""),$tag); |
1489
|
|
|
|
|
|
|
} |
1490
|
|
|
|
|
|
|
else { |
1491
|
12
|
|
|
|
|
119
|
return sprintf("$prolog$indent<%s%s />$epilog$indent",$tag,$tagattrs); |
1492
|
|
|
|
|
|
|
} |
1493
|
|
|
|
|
|
|
} |
1494
|
|
|
|
|
|
|
|
1495
|
|
|
|
|
|
|
sub xmlize { |
1496
|
81
|
|
|
81
|
|
104
|
my $self = shift; |
1497
|
81
|
|
|
|
|
83
|
my($name, $attrs, $values, $id) = @{$_[0]}; |
|
81
|
|
|
|
|
163
|
|
1498
|
81
|
|
50
|
|
|
179
|
$attrs ||= {}; |
1499
|
|
|
|
|
|
|
|
1500
|
81
|
|
|
|
|
202
|
local $self->{_level} = $self->{_level} + 1; |
1501
|
|
|
|
|
|
|
|
1502
|
81
|
100
|
|
|
|
181
|
return $self->tag($name, $attrs) |
1503
|
|
|
|
|
|
|
unless defined $values; |
1504
|
|
|
|
|
|
|
|
1505
|
70
|
100
|
|
|
|
207
|
return $self->tag($name, $attrs, $values) |
1506
|
|
|
|
|
|
|
unless ref $values eq "ARRAY"; |
1507
|
|
|
|
|
|
|
|
1508
|
52
|
100
|
|
|
|
158
|
return $self->tag($name, {%$attrs, href => '#'.$self->multiref_anchor($id)}) |
1509
|
|
|
|
|
|
|
if $self->is_href($id, delete($attrs->{_id})); |
1510
|
|
|
|
|
|
|
|
1511
|
|
|
|
|
|
|
# we have seen this element as a reference |
1512
|
51
|
100
|
66
|
|
|
298
|
if (defined $id && $self->{ _seen }->{ $id }->{ multiref}) { |
1513
|
1
|
|
|
|
|
5
|
return $self->tag($name, |
1514
|
|
|
|
|
|
|
{ |
1515
|
|
|
|
|
|
|
%$attrs, id => $self->multiref_anchor($id) |
1516
|
|
|
|
|
|
|
}, |
1517
|
1
|
|
|
|
|
7
|
map {$self->xmlize($_)} @$values |
1518
|
|
|
|
|
|
|
); |
1519
|
|
|
|
|
|
|
} |
1520
|
|
|
|
|
|
|
else { |
1521
|
50
|
|
|
|
|
97
|
return $self->tag($name, $attrs, map {$self->xmlize($_)} @$values); |
|
58
|
|
|
|
|
208
|
|
1522
|
|
|
|
|
|
|
} |
1523
|
|
|
|
|
|
|
} |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
sub uriformethod { |
1526
|
12
|
|
|
12
|
|
26
|
my $self = shift; |
1527
|
|
|
|
|
|
|
|
1528
|
12
|
|
33
|
|
|
143
|
my $method_is_data = ref $_[0] && UNIVERSAL::isa($_[0] => 'SOAP::Data'); |
1529
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
# drop prefix from method that could be string or SOAP::Data object |
1531
|
12
|
50
|
|
|
|
102
|
my($prefix, $method) = $method_is_data |
1532
|
|
|
|
|
|
|
? ($_[0]->prefix, $_[0]->name) |
1533
|
|
|
|
|
|
|
: SOAP::Utils::splitqname($_[0]); |
1534
|
|
|
|
|
|
|
|
1535
|
12
|
|
|
|
|
26
|
my $attr = {reverse %{$self->namespaces}}; |
|
12
|
|
|
|
|
56
|
|
1536
|
|
|
|
|
|
|
# try to define namespace that could be stored as |
1537
|
|
|
|
|
|
|
# a) method is SOAP::Data |
1538
|
|
|
|
|
|
|
# ? attribute in method's element as xmlns= or xmlns:${prefix}= |
1539
|
|
|
|
|
|
|
# : uri |
1540
|
|
|
|
|
|
|
# b) attribute in Envelope element as xmlns= or xmlns:${prefix}= |
1541
|
|
|
|
|
|
|
# c) no prefix or prefix equal serializer->envprefix |
1542
|
|
|
|
|
|
|
# ? '', but see comment below |
1543
|
|
|
|
|
|
|
# : die with error message |
1544
|
12
|
50
|
0
|
|
|
82
|
my $uri = $method_is_data |
1545
|
|
|
|
|
|
|
? ref $_[0]->attr && ($_[0]->attr->{$prefix ? "xmlns:$prefix" : 'xmlns'} || $_[0]->uri) |
1546
|
|
|
|
|
|
|
: $self->uri; |
1547
|
|
|
|
|
|
|
|
1548
|
12
|
50
|
0
|
|
|
47
|
defined $uri or $uri = $attr->{$prefix || ''}; |
1549
|
|
|
|
|
|
|
|
1550
|
12
|
0
|
0
|
|
|
42
|
defined $uri or $uri = !$prefix || $prefix eq $self->envprefix |
|
|
50
|
0
|
|
|
|
|
1551
|
|
|
|
|
|
|
# still in doubts what should namespace be in this case |
1552
|
|
|
|
|
|
|
# but will keep it like this for now and be compatible with our server |
1553
|
|
|
|
|
|
|
? ( $method_is_data |
1554
|
|
|
|
|
|
|
&& $^W |
1555
|
|
|
|
|
|
|
&& warn("URI is not provided as an attribute for method ($method)\n"), |
1556
|
|
|
|
|
|
|
'' |
1557
|
|
|
|
|
|
|
) |
1558
|
|
|
|
|
|
|
: die "Can't find namespace for method ($prefix:$method)\n"; |
1559
|
|
|
|
|
|
|
|
1560
|
12
|
|
|
|
|
78
|
return ($uri, $method); |
1561
|
|
|
|
|
|
|
} |
1562
|
|
|
|
|
|
|
|
1563
|
3
|
|
|
3
|
|
13
|
sub serialize { SOAP::Trace::trace('()'); |
1564
|
3
|
|
|
|
|
12
|
my $self = shift->new; |
1565
|
3
|
50
|
|
|
|
13
|
@_ == 1 or Carp::croak "serialize() method accepts one parameter"; |
1566
|
|
|
|
|
|
|
|
1567
|
3
|
|
|
|
|
13
|
$self->seen({}); # reinitialize multiref table |
1568
|
3
|
|
|
|
|
13
|
my($encoded) = $self->encode_object($_[0]); |
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
# now encode multirefs if any |
1571
|
|
|
|
|
|
|
# v -------------- subelements of Envelope |
1572
|
3
|
100
|
|
|
|
12
|
push(@{$encoded->[2]}, $self->encode_multirefs) if ref $encoded->[2]; |
|
2
|
|
|
|
|
9
|
|
1573
|
3
|
|
|
|
|
13
|
return $self->xmlize($encoded); |
1574
|
|
|
|
|
|
|
} |
1575
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
sub envelope { |
1577
|
19
|
|
|
19
|
|
63
|
SOAP::Trace::trace('()'); |
1578
|
19
|
|
|
|
|
69
|
my $self = shift->new; |
1579
|
19
|
|
|
|
|
40
|
my $type = shift; |
1580
|
19
|
|
|
|
|
35
|
my(@parameters, @header); |
1581
|
19
|
|
|
|
|
59
|
for (@_) { |
1582
|
|
|
|
|
|
|
# Find all the SOAP Headers |
1583
|
31
|
50
|
100
|
|
|
490
|
if (defined($_) && ref($_) && UNIVERSAL::isa($_ => 'SOAP::Header')) { |
|
|
50
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1584
|
0
|
|
|
|
|
0
|
push(@header, $_); |
1585
|
|
|
|
|
|
|
} |
1586
|
|
|
|
|
|
|
# Find all the SOAP Message Parts (attachments) |
1587
|
|
|
|
|
|
|
elsif (defined($_) && ref($_) && $self->context |
1588
|
|
|
|
|
|
|
&& $self->context->packager->is_supported_part($_) |
1589
|
|
|
|
|
|
|
) { |
1590
|
0
|
|
|
|
|
0
|
$self->context->packager->push_part($_); |
1591
|
|
|
|
|
|
|
} |
1592
|
|
|
|
|
|
|
# Find all the SOAP Body elements |
1593
|
|
|
|
|
|
|
else { |
1594
|
|
|
|
|
|
|
# proposed resolution for [ 1700326 ] encode_data called incorrectly in envelope |
1595
|
31
|
|
|
|
|
85
|
push(@parameters, $_); |
1596
|
|
|
|
|
|
|
# push (@parameters, SOAP::Utils::encode_data($_)); |
1597
|
|
|
|
|
|
|
} |
1598
|
|
|
|
|
|
|
} |
1599
|
19
|
50
|
|
|
|
83
|
my $header = @header ? SOAP::Data->set_value(@header) : undef; |
1600
|
19
|
|
|
|
|
30
|
my($body,$parameters); |
1601
|
19
|
100
|
66
|
|
|
108
|
if ($type eq 'method' || $type eq 'response') { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1602
|
17
|
|
|
|
|
62
|
SOAP::Trace::method(@parameters); |
1603
|
|
|
|
|
|
|
|
1604
|
17
|
|
|
|
|
34
|
my $method = shift(@parameters); |
1605
|
|
|
|
|
|
|
# or die "Unspecified method for SOAP call\n"; |
1606
|
|
|
|
|
|
|
|
1607
|
17
|
100
|
|
|
|
68
|
$parameters = @parameters ? SOAP::Data->set_value(@parameters) : undef; |
1608
|
17
|
50
|
|
|
|
196
|
if (!defined($method)) {} |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
elsif (UNIVERSAL::isa($method => 'SOAP::Data')) { |
1610
|
0
|
|
|
|
|
0
|
$body = $method; |
1611
|
|
|
|
|
|
|
} |
1612
|
|
|
|
|
|
|
elsif ($self->use_default_ns) { |
1613
|
14
|
100
|
|
|
|
51
|
if ($self->{'_ns_uri'}) { |
1614
|
13
|
|
|
|
|
78
|
$body = SOAP::Data->name($method) |
1615
|
|
|
|
|
|
|
->attr({'xmlns' => $self->{'_ns_uri'} } ); |
1616
|
|
|
|
|
|
|
} |
1617
|
|
|
|
|
|
|
else { |
1618
|
1
|
|
|
|
|
3
|
$body = SOAP::Data->name($method); |
1619
|
|
|
|
|
|
|
} |
1620
|
|
|
|
|
|
|
} |
1621
|
|
|
|
|
|
|
else { |
1622
|
|
|
|
|
|
|
# Commented out by Byrne on 1/4/2006 - to address default namespace problems |
1623
|
|
|
|
|
|
|
# $body = SOAP::Data->name($method)->uri($self->{'_ns_uri'}); |
1624
|
|
|
|
|
|
|
# $body = $body->prefix($self->{'_ns_prefix'}) if ($self->{'_ns_prefix'}); |
1625
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
# Added by Byrne on 1/4/2006 - to avoid the unnecessary creation of a new |
1627
|
|
|
|
|
|
|
# namespace |
1628
|
|
|
|
|
|
|
# Begin New Code (replaces code commented out above) |
1629
|
3
|
|
|
|
|
11
|
$body = SOAP::Data->name($method); |
1630
|
3
|
|
|
|
|
18
|
my $pre = $self->find_prefix($self->{'_ns_uri'}); |
1631
|
3
|
50
|
|
|
|
18
|
$body = $body->prefix($pre) if ($self->{'_ns_prefix'}); |
1632
|
|
|
|
|
|
|
# End new code |
1633
|
|
|
|
|
|
|
} |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
# This is breaking a unit test right now... |
1636
|
|
|
|
|
|
|
# proposed resolution for [ 1700326 ] encode_data called incorrectly in envelope |
1637
|
|
|
|
|
|
|
# $body->set_value(SOAP::Utils::encode_data($parameters ? \$parameters : ())) |
1638
|
|
|
|
|
|
|
# if $body; |
1639
|
|
|
|
|
|
|
# must call encode_data on nothing to enforce xsi:nil="true" to be set. |
1640
|
17
|
100
|
|
|
|
126
|
$body->set_value($parameters ? \$parameters : SOAP::Utils::encode_data()) if $body; |
|
|
50
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
} |
1642
|
|
|
|
|
|
|
elsif ($type eq 'fault') { |
1643
|
2
|
|
|
|
|
15
|
SOAP::Trace::fault(@parameters); |
1644
|
|
|
|
|
|
|
# -> attr({'xmlns' => ''}) |
1645
|
|
|
|
|
|
|
# Parameter order fixed thanks to Tom Fischer |
1646
|
|
|
|
|
|
|
$body = SOAP::Data-> name(SOAP::Utils::qualify($self->envprefix => 'Fault')) |
1647
|
|
|
|
|
|
|
-> value(\SOAP::Data->set_value( |
1648
|
|
|
|
|
|
|
SOAP::Data->name(faultcode => SOAP::Utils::qualify($self->envprefix => $parameters[0]))->type(""), |
1649
|
|
|
|
|
|
|
SOAP::Data->name(faultstring => SOAP::Utils::encode_data($parameters[1]))->type(""), |
1650
|
|
|
|
|
|
|
defined($parameters[3]) |
1651
|
|
|
|
|
|
|
? SOAP::Data->name(faultactor => $parameters[3])->type("") |
1652
|
|
|
|
|
|
|
: (), |
1653
|
|
|
|
|
|
|
defined($parameters[2]) |
1654
|
2
|
100
|
|
|
|
9
|
? SOAP::Data->name(detail => do{ |
|
|
100
|
|
|
|
|
|
1655
|
1
|
|
|
|
|
2
|
my $detail = $parameters[2]; |
1656
|
1
|
50
|
|
|
|
10
|
ref $detail |
1657
|
|
|
|
|
|
|
? \$detail |
1658
|
|
|
|
|
|
|
: SOAP::Utils::encode_data($detail) |
1659
|
|
|
|
|
|
|
}) |
1660
|
|
|
|
|
|
|
: (), |
1661
|
|
|
|
|
|
|
)); |
1662
|
|
|
|
|
|
|
} |
1663
|
|
|
|
|
|
|
elsif ($type eq 'freeform') { |
1664
|
0
|
|
|
|
|
0
|
SOAP::Trace::freeform(@parameters); |
1665
|
0
|
|
|
|
|
0
|
$body = SOAP::Data->set_value(@parameters); |
1666
|
|
|
|
|
|
|
} |
1667
|
|
|
|
|
|
|
elsif (!defined($type)) { |
1668
|
|
|
|
|
|
|
# This occurs when the Body is intended to be null. When no method has been |
1669
|
|
|
|
|
|
|
# passed in of any kind. |
1670
|
|
|
|
|
|
|
} |
1671
|
|
|
|
|
|
|
else { |
1672
|
0
|
|
|
|
|
0
|
die "Wrong type of envelope ($type) for SOAP call\n"; |
1673
|
|
|
|
|
|
|
} |
1674
|
|
|
|
|
|
|
|
1675
|
19
|
|
|
|
|
63
|
$self->{ _seen } = {}; # reinitialize multiref table |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
# Build the envelope |
1678
|
|
|
|
|
|
|
# Right now it is possible for $body to be a SOAP::Data element that has not |
1679
|
|
|
|
|
|
|
# XML escaped any values. How do you remedy this? |
1680
|
19
|
50
|
|
|
|
97
|
my($encoded) = $self->encode_object( |
|
|
50
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
SOAP::Data->name( |
1682
|
|
|
|
|
|
|
SOAP::Utils::qualify($self->envprefix => 'Envelope') => \SOAP::Data->value( |
1683
|
|
|
|
|
|
|
($header |
1684
|
|
|
|
|
|
|
? SOAP::Data->name( SOAP::Utils::qualify($self->envprefix => 'Header') => \$header) |
1685
|
|
|
|
|
|
|
: () |
1686
|
|
|
|
|
|
|
), |
1687
|
|
|
|
|
|
|
($body |
1688
|
|
|
|
|
|
|
? SOAP::Data->name(SOAP::Utils::qualify($self->envprefix => 'Body') => \$body) |
1689
|
|
|
|
|
|
|
: SOAP::Data->name(SOAP::Utils::qualify($self->envprefix => 'Body')) ), |
1690
|
|
|
|
|
|
|
) |
1691
|
|
|
|
|
|
|
)->attr($self->attr) |
1692
|
|
|
|
|
|
|
); |
1693
|
|
|
|
|
|
|
|
1694
|
19
|
100
|
|
|
|
101
|
$self->signature($parameters->signature) if ref $parameters; |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
# IMHO multirefs should be encoded after Body, but only some |
1697
|
|
|
|
|
|
|
# toolkits understand this encoding, so we'll keep them for now (04/15/2001) |
1698
|
|
|
|
|
|
|
# as the last element inside the Body |
1699
|
|
|
|
|
|
|
# v -------------- subelements of Envelope |
1700
|
|
|
|
|
|
|
# vv -------- last of them (Body) |
1701
|
|
|
|
|
|
|
# v --- subelements |
1702
|
19
|
50
|
|
|
|
126
|
push(@{$encoded->[2]->[-1]->[2]}, $self->encode_multirefs) if ref $encoded->[2]->[-1]->[2]; |
|
19
|
|
|
|
|
113
|
|
1703
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
# Sometimes SOAP::Serializer is invoked statically when there is no context. |
1705
|
|
|
|
|
|
|
# So first check to see if a context exists. |
1706
|
|
|
|
|
|
|
# TODO - a context needs to be initialized by a constructor? |
1707
|
19
|
100
|
66
|
|
|
89
|
if ($self->context && $self->context->packager->parts) { |
1708
|
|
|
|
|
|
|
# TODO - this needs to be called! Calling it though wraps the payload twice! |
1709
|
|
|
|
|
|
|
# return $self->context->packager->package($self->xmlize($encoded)); |
1710
|
|
|
|
|
|
|
} |
1711
|
|
|
|
|
|
|
|
1712
|
19
|
|
|
|
|
86
|
return $self->xmlize($encoded); |
1713
|
|
|
|
|
|
|
} |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
# ====================================================================== |
1716
|
|
|
|
|
|
|
|
1717
|
|
|
|
|
|
|
package SOAP::Parser; |
1718
|
|
|
|
|
|
|
|
1719
|
15
|
|
|
15
|
|
38
|
sub DESTROY { SOAP::Trace::objects('()') } |
1720
|
|
|
|
|
|
|
|
1721
|
|
|
|
|
|
|
sub xmlparser { |
1722
|
18
|
|
|
18
|
|
42
|
my $self = shift; |
1723
|
|
|
|
|
|
|
return eval { |
1724
|
|
|
|
|
|
|
$SOAP::Constants::DO_NOT_USE_XML_PARSER |
1725
|
|
|
|
|
|
|
? undef |
1726
|
|
|
|
|
|
|
: do { |
1727
|
|
|
|
|
|
|
require XML::Parser; |
1728
|
|
|
|
|
|
|
XML::Parser->new() } |
1729
|
|
|
|
|
|
|
} |
1730
|
18
|
|
50
|
|
|
39
|
|| eval { require XML::Parser::Lite; XML::Parser::Lite->new } |
1731
|
|
|
|
|
|
|
|| die "XML::Parser is not @{[$SOAP::Constants::DO_NOT_USE_XML_PARSER ? 'used' : 'available']} and ", $@; |
1732
|
|
|
|
|
|
|
} |
1733
|
|
|
|
|
|
|
|
1734
|
|
|
|
|
|
|
sub parser { |
1735
|
18
|
|
|
18
|
|
68
|
my $self = shift->new; |
1736
|
|
|
|
|
|
|
|
1737
|
|
|
|
|
|
|
# set the parser if passed |
1738
|
18
|
50
|
|
|
|
80
|
if (my $parser = shift) { |
1739
|
0
|
|
|
|
|
0
|
$self->{'_parser'} = shift; |
1740
|
0
|
|
|
|
|
0
|
return $self; |
1741
|
|
|
|
|
|
|
} |
1742
|
|
|
|
|
|
|
|
1743
|
|
|
|
|
|
|
# else return the parser or use XML::Parser::Lite |
1744
|
18
|
|
33
|
|
|
236
|
return ($self->{'_parser'} ||= $self->xmlparser); |
1745
|
|
|
|
|
|
|
} |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
sub new { |
1748
|
39
|
|
|
39
|
|
74
|
my $self = shift; |
1749
|
39
|
100
|
|
|
|
143
|
return $self if ref $self; |
1750
|
21
|
|
|
|
|
41
|
my $class = $self; |
1751
|
21
|
|
|
|
|
56
|
SOAP::Trace::objects('()'); |
1752
|
21
|
|
|
|
|
182
|
return bless {_parser => shift}, $class; |
1753
|
|
|
|
|
|
|
} |
1754
|
|
|
|
|
|
|
|
1755
|
18
|
|
|
18
|
|
62
|
sub decode { SOAP::Trace::trace('()'); |
1756
|
18
|
|
|
|
|
31
|
my $self = shift; |
1757
|
|
|
|
|
|
|
|
1758
|
|
|
|
|
|
|
$self->parser->setHandlers( |
1759
|
0
|
|
|
0
|
|
0
|
Final => sub { shift; $self->final(@_) }, |
|
0
|
|
|
|
|
0
|
|
1760
|
0
|
|
|
0
|
|
0
|
Start => sub { shift; $self->start(@_) }, |
|
0
|
|
|
|
|
0
|
|
1761
|
0
|
|
|
0
|
|
0
|
End => sub { shift; $self->end(@_) }, |
|
0
|
|
|
|
|
0
|
|
1762
|
0
|
|
|
0
|
|
0
|
Char => sub { shift; $self->char(@_) }, |
|
0
|
|
|
|
|
0
|
|
1763
|
0
|
|
|
0
|
|
0
|
ExternEnt => sub { shift; die "External entity (pointing to '$_[1]') is not allowed" }, |
|
0
|
|
|
|
|
0
|
|
1764
|
18
|
|
|
|
|
93
|
); |
1765
|
|
|
|
|
|
|
# my $parsed = $self->parser->parse($_[0]); |
1766
|
|
|
|
|
|
|
# return $parsed; |
1767
|
|
|
|
|
|
|
# |
1768
|
0
|
|
|
|
|
0
|
my $ret = undef; |
1769
|
0
|
|
|
|
|
0
|
eval { |
1770
|
0
|
|
|
|
|
0
|
$ret = $self->parser->parse($_[0]); |
1771
|
|
|
|
|
|
|
}; |
1772
|
0
|
0
|
|
|
|
0
|
if ($@) { |
1773
|
0
|
|
|
|
|
0
|
$self->final; # Clean up in the event of an error |
1774
|
0
|
|
|
|
|
0
|
die $@; # Pass back the error |
1775
|
|
|
|
|
|
|
} |
1776
|
0
|
|
|
|
|
0
|
return $ret; |
1777
|
|
|
|
|
|
|
} |
1778
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
sub final { |
1780
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1781
|
|
|
|
|
|
|
|
1782
|
|
|
|
|
|
|
# clean handlers, otherwise SOAP::Parser won't be deleted: |
1783
|
|
|
|
|
|
|
# it refers to XML::Parser which refers to subs from SOAP::Parser |
1784
|
|
|
|
|
|
|
# Thanks to Ryan Adams |
1785
|
|
|
|
|
|
|
# and Craig Johnston |
1786
|
|
|
|
|
|
|
# checked by number of tests in t/02-payload.t |
1787
|
|
|
|
|
|
|
|
1788
|
0
|
|
|
|
|
0
|
undef $self->{_values}; |
1789
|
0
|
|
|
|
|
0
|
$self->parser->setHandlers( |
1790
|
|
|
|
|
|
|
Final => undef, |
1791
|
|
|
|
|
|
|
Start => undef, |
1792
|
|
|
|
|
|
|
End => undef, |
1793
|
|
|
|
|
|
|
Char => undef, |
1794
|
|
|
|
|
|
|
ExternEnt => undef, |
1795
|
|
|
|
|
|
|
); |
1796
|
0
|
|
|
|
|
0
|
$self->{_done}; |
1797
|
|
|
|
|
|
|
} |
1798
|
|
|
|
|
|
|
|
1799
|
0
|
|
|
0
|
|
0
|
sub start { push @{shift->{_values}}, [shift, {@_}] } |
|
0
|
|
|
|
|
0
|
|
1800
|
|
|
|
|
|
|
|
1801
|
|
|
|
|
|
|
# string concatenation changed to arrays which should improve performance |
1802
|
|
|
|
|
|
|
# for strings with many entity-encoded elements. |
1803
|
|
|
|
|
|
|
# Thanks to Mathieu Longtin |
1804
|
0
|
|
|
0
|
|
0
|
sub char { push @{shift->{_values}->[-1]->[3]}, shift } |
|
0
|
|
|
|
|
0
|
|
1805
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
sub end { |
1807
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1808
|
0
|
|
|
|
|
0
|
my $done = pop @{$self->{_values}}; |
|
0
|
|
|
|
|
0
|
|
1809
|
0
|
|
|
|
|
0
|
$done->[2] = defined $done->[3] |
1810
|
0
|
0
|
|
|
|
0
|
? join('',@{$done->[3]}) |
|
|
0
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
: '' unless ref $done->[2]; |
1812
|
0
|
|
|
|
|
0
|
undef $done->[3]; |
1813
|
0
|
|
|
|
|
0
|
@{$self->{_values}} |
|
0
|
|
|
|
|
0
|
|
1814
|
0
|
0
|
|
|
|
0
|
? (push @{$self->{_values}->[-1]->[2]}, $done) |
1815
|
|
|
|
|
|
|
: ($self->{_done} = $done); |
1816
|
|
|
|
|
|
|
} |
1817
|
|
|
|
|
|
|
|
1818
|
|
|
|
|
|
|
# ====================================================================== |
1819
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
package SOAP::SOM; |
1821
|
|
|
|
|
|
|
|
1822
|
25
|
|
|
25
|
|
202
|
use Carp (); |
|
25
|
|
|
|
|
44
|
|
|
25
|
|
|
|
|
412
|
|
1823
|
25
|
|
|
25
|
|
112
|
use SOAP::Lite::Utils; |
|
25
|
|
|
|
|
37
|
|
|
25
|
|
|
|
|
161
|
|
1824
|
|
|
|
|
|
|
|
1825
|
|
|
|
|
|
|
sub BEGIN { |
1826
|
25
|
|
|
25
|
|
100
|
no strict 'refs'; |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
6809
|
|
1827
|
25
|
|
|
25
|
|
302
|
my %path = ( |
1828
|
|
|
|
|
|
|
root => '/', |
1829
|
|
|
|
|
|
|
envelope => '/Envelope', |
1830
|
|
|
|
|
|
|
body => '/Envelope/Body', |
1831
|
|
|
|
|
|
|
header => '/Envelope/Header', |
1832
|
|
|
|
|
|
|
headers => '/Envelope/Header/[>0]', |
1833
|
|
|
|
|
|
|
fault => '/Envelope/Body/Fault', |
1834
|
|
|
|
|
|
|
faultcode => '/Envelope/Body/Fault/faultcode', |
1835
|
|
|
|
|
|
|
faultstring => '/Envelope/Body/Fault/faultstring', |
1836
|
|
|
|
|
|
|
faultactor => '/Envelope/Body/Fault/faultactor', |
1837
|
|
|
|
|
|
|
faultdetail => '/Envelope/Body/Fault/detail', |
1838
|
|
|
|
|
|
|
); |
1839
|
25
|
|
|
|
|
139
|
for my $method (keys %path) { |
1840
|
|
|
|
|
|
|
*$method = sub { |
1841
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1842
|
0
|
0
|
|
|
|
0
|
ref $self or return $path{$method}; |
1843
|
0
|
0
|
|
|
|
0
|
Carp::croak "Method '$method' is readonly and doesn't accept any parameters" if @_; |
1844
|
0
|
|
|
|
|
0
|
return $self->valueof($path{$method}); |
1845
|
250
|
|
|
|
|
1056
|
}; |
1846
|
|
|
|
|
|
|
} |
1847
|
25
|
|
|
|
|
161
|
my %results = ( |
1848
|
|
|
|
|
|
|
method => '/Envelope/Body/[1]', |
1849
|
|
|
|
|
|
|
result => '/Envelope/Body/[1]/[1]', |
1850
|
|
|
|
|
|
|
freeform => '/Envelope/Body/[>0]', |
1851
|
|
|
|
|
|
|
paramsin => '/Envelope/Body/[1]/[>0]', |
1852
|
|
|
|
|
|
|
paramsall => '/Envelope/Body/[1]/[>0]', |
1853
|
|
|
|
|
|
|
paramsout => '/Envelope/Body/[1]/[>1]' |
1854
|
|
|
|
|
|
|
); |
1855
|
25
|
|
|
|
|
69
|
for my $method (keys %results) { |
1856
|
|
|
|
|
|
|
*$method = sub { |
1857
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1858
|
0
|
0
|
|
|
|
0
|
ref $self or return $results{$method}; |
1859
|
0
|
0
|
|
|
|
0
|
Carp::croak "Method '$method' is readonly and doesn't accept any parameters" if @_; |
1860
|
0
|
0
|
|
|
|
0
|
defined $self->fault ? return : return $self->valueof($results{$method}); |
1861
|
150
|
|
|
|
|
712
|
}; |
1862
|
|
|
|
|
|
|
} |
1863
|
|
|
|
|
|
|
|
1864
|
25
|
|
|
|
|
48
|
for my $method (qw(o_child o_value o_lname o_lattr o_qname)) { # import from SOAP::Utils |
1865
|
125
|
|
|
|
|
122
|
*$method = \&{'SOAP::Utils::'.$method}; |
|
125
|
|
|
|
|
490
|
|
1866
|
|
|
|
|
|
|
} |
1867
|
|
|
|
|
|
|
|
1868
|
25
|
|
|
|
|
156
|
__PACKAGE__->__mk_accessors('context'); |
1869
|
|
|
|
|
|
|
|
1870
|
|
|
|
|
|
|
} |
1871
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
# use object in boolean context return true/false on last match |
1873
|
|
|
|
|
|
|
# Ex.: $som->match('//Fault') ? 'SOAP call failed' : 'success'; |
1874
|
25
|
|
|
25
|
|
149
|
use overload fallback => 1, 'bool' => sub { @{shift->{_current}} > 0 }; |
|
25
|
|
|
0
|
|
42
|
|
|
25
|
|
|
|
|
248
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1875
|
|
|
|
|
|
|
|
1876
|
0
|
|
|
0
|
|
0
|
sub DESTROY { SOAP::Trace::objects('()') } |
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
sub new { |
1879
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1880
|
0
|
|
0
|
|
|
0
|
my $class = ref($self) || $self; |
1881
|
0
|
|
|
|
|
0
|
my $content = shift; |
1882
|
0
|
|
|
|
|
0
|
SOAP::Trace::objects('()'); |
1883
|
0
|
|
|
|
|
0
|
return bless { _content => $content, _current => [$content] } => $class; |
1884
|
|
|
|
|
|
|
} |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
sub parts { |
1887
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1888
|
0
|
0
|
|
|
|
0
|
if (@_) { |
1889
|
0
|
|
|
|
|
0
|
$self->context->packager->parts(@_); |
1890
|
0
|
|
|
|
|
0
|
return $self; |
1891
|
|
|
|
|
|
|
} |
1892
|
|
|
|
|
|
|
else { |
1893
|
0
|
|
|
|
|
0
|
return $self->context->packager->parts; |
1894
|
|
|
|
|
|
|
} |
1895
|
|
|
|
|
|
|
} |
1896
|
|
|
|
|
|
|
|
1897
|
|
|
|
|
|
|
sub is_multipart { |
1898
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1899
|
0
|
|
|
|
|
0
|
return defined($self->parts); |
1900
|
|
|
|
|
|
|
} |
1901
|
|
|
|
|
|
|
|
1902
|
|
|
|
|
|
|
sub current { |
1903
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1904
|
0
|
0
|
|
|
|
0
|
$self->{_current} = [@_], return $self if @_; |
1905
|
0
|
0
|
|
|
|
0
|
return wantarray ? @{$self->{_current}} : $self->{_current}->[0]; |
|
0
|
|
|
|
|
0
|
|
1906
|
|
|
|
|
|
|
} |
1907
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
sub valueof { |
1909
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1910
|
0
|
|
|
|
|
0
|
local $self->{_current} = $self->{_current}; |
1911
|
0
|
0
|
|
|
|
0
|
$self->match(shift) if @_; |
1912
|
|
|
|
|
|
|
return wantarray |
1913
|
0
|
|
|
|
|
0
|
? map {o_value($_)} @{$self->{_current}} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1914
|
0
|
0
|
|
|
|
0
|
: @{$self->{_current}} ? o_value($self->{_current}->[0]) : undef; |
|
|
0
|
|
|
|
|
|
1915
|
|
|
|
|
|
|
} |
1916
|
|
|
|
|
|
|
|
1917
|
|
|
|
|
|
|
sub headerof { # SOAP::Header is the same as SOAP::Data, so just rebless it |
1918
|
|
|
|
|
|
|
wantarray |
1919
|
0
|
|
|
|
|
0
|
? map { bless $_ => 'SOAP::Header' } shift->dataof(@_) |
1920
|
0
|
0
|
|
0
|
|
0
|
: do { # header returned by ->dataof can be undef in scalar context |
1921
|
0
|
|
|
|
|
0
|
my $header = shift->dataof(@_); |
1922
|
0
|
0
|
|
|
|
0
|
ref $header ? bless($header => 'SOAP::Header') : undef; |
1923
|
|
|
|
|
|
|
}; |
1924
|
|
|
|
|
|
|
} |
1925
|
|
|
|
|
|
|
|
1926
|
|
|
|
|
|
|
sub dataof { |
1927
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1928
|
0
|
|
|
|
|
0
|
local $self->{_current} = $self->{_current}; |
1929
|
0
|
0
|
|
|
|
0
|
$self->match(shift) if @_; |
1930
|
|
|
|
|
|
|
return wantarray |
1931
|
0
|
|
|
|
|
0
|
? map {$self->_as_data($_)} @{$self->{_current}} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1932
|
0
|
0
|
|
|
|
0
|
: @{$self->{_current}} |
|
|
0
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
? $self->_as_data($self->{_current}->[0]) |
1934
|
|
|
|
|
|
|
: undef; |
1935
|
|
|
|
|
|
|
} |
1936
|
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
sub namespaceuriof { |
1938
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1939
|
0
|
|
|
|
|
0
|
local $self->{_current} = $self->{_current}; |
1940
|
0
|
0
|
|
|
|
0
|
$self->match(shift) if @_; |
1941
|
|
|
|
|
|
|
return wantarray |
1942
|
0
|
|
|
|
|
0
|
? map {(SOAP::Utils::splitlongname(o_lname($_)))[0]} @{$self->{_current}} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1943
|
0
|
0
|
|
|
|
0
|
: @{$self->{_current}} ? (SOAP::Utils::splitlongname(o_lname($self->{_current}->[0])))[0] : undef; |
|
|
0
|
|
|
|
|
|
1944
|
|
|
|
|
|
|
} |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
#sub _as_data { |
1947
|
|
|
|
|
|
|
# my $self = shift; |
1948
|
|
|
|
|
|
|
# my $pointer = shift; |
1949
|
|
|
|
|
|
|
# |
1950
|
|
|
|
|
|
|
# SOAP::Data |
1951
|
|
|
|
|
|
|
# -> new(prefix => '', name => o_qname($pointer), name => o_lname($pointer), attr => o_lattr($pointer)) |
1952
|
|
|
|
|
|
|
# -> set_value(o_value($pointer)); |
1953
|
|
|
|
|
|
|
#} |
1954
|
|
|
|
|
|
|
|
1955
|
|
|
|
|
|
|
sub _as_data { |
1956
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1957
|
0
|
|
|
|
|
0
|
my $node = shift; |
1958
|
|
|
|
|
|
|
|
1959
|
0
|
|
|
|
|
0
|
my $data = SOAP::Data->new( prefix => '', |
1960
|
|
|
|
|
|
|
# name => o_qname has side effect: sets namespace ! |
1961
|
|
|
|
|
|
|
name => o_qname($node), |
1962
|
|
|
|
|
|
|
name => o_lname($node), |
1963
|
|
|
|
|
|
|
attr => o_lattr($node) ); |
1964
|
|
|
|
|
|
|
|
1965
|
0
|
0
|
|
|
|
0
|
if ( defined o_child($node) ) { |
1966
|
0
|
|
|
|
|
0
|
my @children; |
1967
|
0
|
|
|
|
|
0
|
foreach my $child ( @{ o_child($node) } ) { |
|
0
|
|
|
|
|
0
|
|
1968
|
0
|
|
|
|
|
0
|
push( @children, $self->_as_data($child) ); |
1969
|
|
|
|
|
|
|
} |
1970
|
0
|
|
|
|
|
0
|
$data->set_value( \SOAP::Data->value(@children) ); |
1971
|
|
|
|
|
|
|
} |
1972
|
|
|
|
|
|
|
else { |
1973
|
0
|
|
|
|
|
0
|
$data->set_value( o_value($node) ); |
1974
|
|
|
|
|
|
|
} |
1975
|
|
|
|
|
|
|
|
1976
|
0
|
|
|
|
|
0
|
return $data; |
1977
|
|
|
|
|
|
|
} |
1978
|
|
|
|
|
|
|
|
1979
|
|
|
|
|
|
|
|
1980
|
|
|
|
|
|
|
sub match { |
1981
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1982
|
0
|
|
|
|
|
0
|
my $path = shift; |
1983
|
|
|
|
|
|
|
$self->{_current} = [ |
1984
|
0
|
|
|
|
|
0
|
$path =~ s!^/!! || !@{$self->{_current}} |
1985
|
|
|
|
|
|
|
? $self->_traverse($self->{_content}, 1 => split '/' => $path) |
1986
|
0
|
0
|
0
|
|
|
0
|
: map {$self->_traverse_tree(o_child($_), split '/' => $path)} @{$self->{_current}} |
|
0
|
|
|
|
|
0
|
|
1987
|
|
|
|
|
|
|
]; |
1988
|
0
|
|
|
|
|
0
|
return $self; |
1989
|
|
|
|
|
|
|
} |
1990
|
|
|
|
|
|
|
|
1991
|
|
|
|
|
|
|
sub _traverse { |
1992
|
0
|
|
|
0
|
|
0
|
my ($self, $pointer, $itself, $path, @path) = @_; |
1993
|
|
|
|
|
|
|
|
1994
|
0
|
0
|
|
|
|
0
|
die "Incorrect parameter" unless $itself =~/^\d+$/; |
1995
|
|
|
|
|
|
|
|
1996
|
0
|
0
|
0
|
|
|
0
|
if ($path && substr($path, 0, 1) eq '{') { |
1997
|
0
|
|
0
|
|
|
0
|
$path = join '/', $path, shift @path while @path && $path !~ /}/; |
1998
|
|
|
|
|
|
|
} |
1999
|
|
|
|
|
|
|
|
2000
|
0
|
0
|
|
|
|
0
|
my($op, $num) = $path =~ /^\[(<=|<|>=|>|=|!=?)?(\d+)\]$/ if defined $path; |
2001
|
|
|
|
|
|
|
|
2002
|
0
|
0
|
|
|
|
0
|
return $pointer unless defined $path; |
2003
|
|
|
|
|
|
|
|
2004
|
0
|
0
|
0
|
|
|
0
|
if (! $op) { |
|
|
0
|
|
|
|
|
|
2005
|
0
|
|
|
|
|
0
|
$op = '=='; |
2006
|
|
|
|
|
|
|
} |
2007
|
|
|
|
|
|
|
elsif ($op eq '=' || $op eq '!') { |
2008
|
0
|
|
|
|
|
0
|
$op .= '='; |
2009
|
|
|
|
|
|
|
} |
2010
|
0
|
|
0
|
|
|
0
|
my $numok = defined $num && eval "$itself $op $num"; |
2011
|
0
|
0
|
0
|
|
|
0
|
my $nameok = (o_lname($pointer) || '') =~ /(?:^|\})$path$/ if defined $path; # name can be with namespace |
2012
|
|
|
|
|
|
|
|
2013
|
0
|
|
|
|
|
0
|
my $anynode = $path eq ''; |
2014
|
0
|
0
|
|
|
|
0
|
unless ($anynode) { |
2015
|
0
|
0
|
|
|
|
0
|
if (@path) { |
2016
|
0
|
0
|
0
|
|
|
0
|
return if defined $num && !$numok || !defined $num && !$nameok; |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2017
|
|
|
|
|
|
|
} |
2018
|
|
|
|
|
|
|
else { |
2019
|
0
|
0
|
0
|
|
|
0
|
return $pointer if defined $num && $numok || !defined $num && $nameok; |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2020
|
0
|
|
|
|
|
0
|
return; |
2021
|
|
|
|
|
|
|
} |
2022
|
|
|
|
|
|
|
} |
2023
|
|
|
|
|
|
|
|
2024
|
0
|
|
|
|
|
0
|
my @walk; |
2025
|
0
|
0
|
|
|
|
0
|
push @walk, $self->_traverse_tree([$pointer], @path) if $anynode; |
2026
|
0
|
0
|
|
|
|
0
|
push @walk, $self->_traverse_tree(o_child($pointer), $anynode ? ($path, @path) : @path); |
2027
|
0
|
|
|
|
|
0
|
return @walk; |
2028
|
|
|
|
|
|
|
} |
2029
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
sub _traverse_tree { |
2031
|
0
|
|
|
0
|
|
0
|
my ($self, $pointer, @path) = @_; |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
# can be list of children or value itself. Traverse only children |
2034
|
0
|
0
|
|
|
|
0
|
return unless ref $pointer eq 'ARRAY'; |
2035
|
|
|
|
|
|
|
|
2036
|
0
|
|
|
|
|
0
|
my $itself = 1; |
2037
|
|
|
|
|
|
|
|
2038
|
0
|
|
|
|
|
0
|
grep {defined} |
|
0
|
|
|
|
|
0
|
|
2039
|
0
|
0
|
0
|
|
|
0
|
map {$self->_traverse($_, $itself++, @path)} |
2040
|
0
|
|
|
|
|
0
|
grep {!ref o_lattr($_) || |
2041
|
|
|
|
|
|
|
!exists o_lattr($_)->{"{$SOAP::Constants::NS_ENC}root"} || |
2042
|
|
|
|
|
|
|
o_lattr($_)->{"{$SOAP::Constants::NS_ENC}root"} ne '0'} |
2043
|
|
|
|
|
|
|
@$pointer; |
2044
|
|
|
|
|
|
|
} |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
# ====================================================================== |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
package SOAP::Deserializer; |
2049
|
|
|
|
|
|
|
|
2050
|
25
|
|
|
25
|
|
30278
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
46
|
|
|
25
|
|
|
|
|
1255
|
|
2051
|
25
|
|
|
25
|
|
117
|
use SOAP::Lite::Utils; |
|
25
|
|
|
|
|
44
|
|
|
25
|
|
|
|
|
103
|
|
2052
|
25
|
|
|
25
|
|
104
|
use Class::Inspector; |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
612
|
|
2053
|
25
|
|
|
25
|
|
14782
|
use URI::Escape qw{uri_unescape}; |
|
25
|
|
|
|
|
30461
|
|
|
25
|
|
|
|
|
2803
|
|
2054
|
|
|
|
|
|
|
|
2055
|
|
|
|
|
|
|
@ISA = qw(SOAP::Cloneable); |
2056
|
|
|
|
|
|
|
|
2057
|
21
|
|
|
21
|
|
69
|
sub DESTROY { SOAP::Trace::objects('()') } |
2058
|
|
|
|
|
|
|
|
2059
|
|
|
|
|
|
|
sub BEGIN { |
2060
|
25
|
|
|
25
|
|
156
|
__PACKAGE__->__mk_accessors( qw(ids hrefs parts parser |
2061
|
|
|
|
|
|
|
base xmlschemas xmlschema context) ); |
2062
|
|
|
|
|
|
|
} |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
# Cache (slow) Class::Inspector results |
2065
|
|
|
|
|
|
|
my %_class_loaded=(); |
2066
|
|
|
|
|
|
|
|
2067
|
|
|
|
|
|
|
sub new { |
2068
|
54
|
|
|
54
|
|
1190
|
my $self = shift; |
2069
|
54
|
100
|
|
|
|
193
|
return $self if ref $self; |
2070
|
21
|
|
|
|
|
36
|
my $class = $self; |
2071
|
21
|
|
|
|
|
59
|
SOAP::Trace::objects('()'); |
2072
|
84
|
|
|
|
|
443
|
return bless { |
2073
|
|
|
|
|
|
|
'_ids' => {}, |
2074
|
|
|
|
|
|
|
'_hrefs' => {}, |
2075
|
|
|
|
|
|
|
'_parser' => SOAP::Parser->new, |
2076
|
|
|
|
|
|
|
'_xmlschemas' => { |
2077
|
|
|
|
|
|
|
$SOAP::Constants::NS_APS => 'SOAP::XMLSchemaApacheSOAP::Deserializer', |
2078
|
|
|
|
|
|
|
# map { |
2079
|
|
|
|
|
|
|
# $_ => $SOAP::Constants::XML_SCHEMAS{$_} . '::Deserializer' |
2080
|
|
|
|
|
|
|
# } keys %SOAP::Constants::XML_SCHEMAS |
2081
|
|
|
|
|
|
|
map { |
2082
|
21
|
|
|
|
|
160
|
$_ => 'SOAP::Lite::Deserializer::' . $SOAP::Constants::XML_SCHEMA_OF{$_} |
2083
|
|
|
|
|
|
|
} keys %SOAP::Constants::XML_SCHEMA_OF |
2084
|
|
|
|
|
|
|
|
2085
|
|
|
|
|
|
|
}, |
2086
|
|
|
|
|
|
|
}, $class; |
2087
|
|
|
|
|
|
|
} |
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
sub is_xml { |
2090
|
|
|
|
|
|
|
# Added check for envelope delivery. Fairly standard with MMDF and sendmail |
2091
|
|
|
|
|
|
|
# Thanks to Chris Davies |
2092
|
19
|
100
|
|
19
|
|
354
|
$_[1] =~ /^\s* || $_[1] !~ /^(?:[\w-]+:|From )/; |
2093
|
|
|
|
|
|
|
} |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
sub baselocation { |
2096
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2097
|
0
|
|
|
|
|
0
|
my $location = shift; |
2098
|
0
|
0
|
|
|
|
0
|
if ($location) { |
2099
|
0
|
|
|
|
|
0
|
my $uri = URI->new($location); |
2100
|
|
|
|
|
|
|
# make absolute location if relative |
2101
|
0
|
0
|
0
|
|
|
0
|
$location = $uri->abs($self->base || 'thismessage:/')->as_string unless $uri->scheme; |
2102
|
|
|
|
|
|
|
} |
2103
|
0
|
|
|
|
|
0
|
return $location; |
2104
|
|
|
|
|
|
|
} |
2105
|
|
|
|
|
|
|
|
2106
|
|
|
|
|
|
|
# Returns the envelope and populates SOAP::Packager with parts |
2107
|
|
|
|
|
|
|
sub decode_parts { |
2108
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
2109
|
1
|
|
|
|
|
4
|
my $env = $self->context->packager->unpackage($_[0],$self->context); |
2110
|
0
|
|
|
|
|
0
|
my $body = $self->parser->decode($env); |
2111
|
|
|
|
|
|
|
# TODO - This shouldn't be here! This is packager specific! |
2112
|
|
|
|
|
|
|
# However this does need to pull out all the cid's |
2113
|
|
|
|
|
|
|
# to populate ids hash with. |
2114
|
0
|
|
|
|
|
0
|
foreach (@{$self->context->packager->parts}) { |
|
0
|
|
|
|
|
0
|
|
2115
|
0
|
|
|
|
|
0
|
my $data = $_->bodyhandle->as_string; |
2116
|
0
|
|
|
|
|
0
|
my $type = $_->head->mime_attr('Content-Type'); |
2117
|
0
|
|
|
|
|
0
|
my $location = $_->head->mime_attr('Content-Location'); |
2118
|
0
|
|
|
|
|
0
|
my $id = $_->head->mime_attr('Content-Id'); |
2119
|
0
|
|
|
|
|
0
|
$location = $self->baselocation($location); |
2120
|
0
|
0
|
0
|
|
|
0
|
my $part = lc($type) eq 'text/xml' && !$SOAP::Constants::DO_NOT_PROCESS_XML_IN_MIME |
2121
|
|
|
|
|
|
|
? $self->parser->decode($data) |
2122
|
|
|
|
|
|
|
: ['mimepart', {}, $data]; |
2123
|
|
|
|
|
|
|
# This below looks like unnecessary bloat!!! |
2124
|
|
|
|
|
|
|
# I should probably dereference the mimepart, provide a callback to get the string data |
2125
|
0
|
0
|
0
|
|
|
0
|
$self->ids->{$1} = $part if ($id && $id =~ m/^<([^>]+)>$/); # strip any leading and trailing brackets |
2126
|
0
|
0
|
|
|
|
0
|
$self->ids->{$location} = $part if $location; |
2127
|
|
|
|
|
|
|
} |
2128
|
0
|
|
|
|
|
0
|
return $body; |
2129
|
|
|
|
|
|
|
} |
2130
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
# decode returns a parsed body in the form of an ARRAY |
2132
|
|
|
|
|
|
|
# each element of the ARRAY is a HASH, ARRAY or SCALAR |
2133
|
|
|
|
|
|
|
sub decode { |
2134
|
19
|
|
|
19
|
|
60
|
my $self = shift->new; # this actually is important |
2135
|
19
|
100
|
|
|
|
84
|
return $self->is_xml($_[0]) |
2136
|
|
|
|
|
|
|
? $self->parser->decode($_[0]) |
2137
|
|
|
|
|
|
|
: $self->decode_parts($_[0]); |
2138
|
|
|
|
|
|
|
} |
2139
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
# deserialize returns a SOAP::SOM object and parses straight |
2141
|
|
|
|
|
|
|
# text as input |
2142
|
|
|
|
|
|
|
sub deserialize { |
2143
|
19
|
|
|
19
|
|
1827
|
SOAP::Trace::trace('()'); |
2144
|
19
|
|
|
|
|
82
|
my $self = shift->new; |
2145
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
# initialize |
2147
|
19
|
|
|
|
|
122
|
$self->hrefs({}); |
2148
|
19
|
|
|
|
|
209
|
$self->ids({}); |
2149
|
|
|
|
|
|
|
|
2150
|
|
|
|
|
|
|
# If the document is XML, then ids will be empty |
2151
|
|
|
|
|
|
|
# If the document is MIME, then ids will hold a list of cids |
2152
|
19
|
|
|
|
|
93
|
my $parsed = $self->decode($_[0]); |
2153
|
|
|
|
|
|
|
|
2154
|
|
|
|
|
|
|
# Having this code here makes multirefs in the Body work, but multirefs |
2155
|
|
|
|
|
|
|
# that reference XML fragments in a MIME part do not work. |
2156
|
0
|
0
|
|
|
|
0
|
if (keys %{$self->ids()}) { |
|
0
|
|
|
|
|
0
|
|
2157
|
0
|
|
|
|
|
0
|
$self->traverse_ids($parsed); |
2158
|
|
|
|
|
|
|
} |
2159
|
|
|
|
|
|
|
else { |
2160
|
|
|
|
|
|
|
# delay - set ids to be traversed later in decode_object, they only get |
2161
|
|
|
|
|
|
|
# traversed if an href is found that is referencing an id. |
2162
|
0
|
|
|
|
|
0
|
$self->ids($parsed); |
2163
|
|
|
|
|
|
|
} |
2164
|
0
|
|
|
|
|
0
|
$self->decode_object($parsed); |
2165
|
0
|
|
|
|
|
0
|
my $som = SOAP::SOM->new($parsed); |
2166
|
0
|
|
|
|
|
0
|
$som->context($self->context); # TODO - try removing this and see if it works! |
2167
|
0
|
|
|
|
|
0
|
return $som; |
2168
|
|
|
|
|
|
|
} |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
sub traverse_ids { |
2171
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2172
|
0
|
|
|
|
|
0
|
my $ref = shift; |
2173
|
0
|
|
|
|
|
0
|
my($undef, $attrs, $children) = @$ref; |
2174
|
|
|
|
|
|
|
# ^^^^^^ to fix nasty error on Mac platform (Carl K. Cunningham) |
2175
|
0
|
0
|
|
|
|
0
|
$self->ids->{$attrs->{'id'}} = $ref if exists $attrs->{'id'}; |
2176
|
0
|
0
|
|
|
|
0
|
return unless ref $children; |
2177
|
0
|
|
|
|
|
0
|
for (@$children) { |
2178
|
0
|
|
|
|
|
0
|
$self->traverse_ids($_) |
2179
|
|
|
|
|
|
|
}; |
2180
|
|
|
|
|
|
|
} |
2181
|
|
|
|
|
|
|
|
2182
|
25
|
|
|
25
|
|
209
|
use constant _ATTRS => 6; |
|
25
|
|
|
|
|
42
|
|
|
25
|
|
|
|
|
2184
|
|
2183
|
25
|
|
|
25
|
|
125
|
use constant _NAME => 5; |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
5454
|
|
2184
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
sub decode_object { |
2186
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2187
|
0
|
|
|
|
|
0
|
my $ref = shift; |
2188
|
0
|
|
|
|
|
0
|
my($name, $attrs_ref, $children, $value) = @$ref; |
2189
|
|
|
|
|
|
|
|
2190
|
0
|
|
|
|
|
0
|
my %attrs = %{ $attrs_ref }; |
|
0
|
|
|
|
|
0
|
|
2191
|
|
|
|
|
|
|
|
2192
|
0
|
|
|
|
|
0
|
$ref->[ _ATTRS ] = \%attrs; # make a copy for long attributes |
2193
|
|
|
|
|
|
|
|
2194
|
25
|
|
|
25
|
|
146
|
use vars qw(%uris); |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
13299
|
|
2195
|
|
|
|
|
|
|
local %uris = (%uris, map { |
2196
|
0
|
|
|
|
|
0
|
do { (my $ns = $_) =~ s/^xmlns:?//; $ns } => delete $attrs{$_} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2197
|
0
|
|
|
|
|
0
|
} grep {/^xmlns(:|$)/} keys %attrs); |
2198
|
|
|
|
|
|
|
|
2199
|
0
|
|
|
|
|
0
|
foreach (keys %attrs) { |
2200
|
0
|
0
|
|
|
|
0
|
next unless m/^($SOAP::Constants::NSMASK?):($SOAP::Constants::NSMASK)$/; |
2201
|
|
|
|
|
|
|
|
2202
|
|
|
|
|
|
|
$1 =~ /^[xX][mM][lL]/ || |
2203
|
|
|
|
|
|
|
$uris{$1} && |
2204
|
0
|
0
|
0
|
|
|
0
|
do { |
|
|
|
0
|
|
|
|
|
2205
|
0
|
|
|
|
|
0
|
$attrs{SOAP::Utils::longname($uris{$1}, $2)} = do { |
2206
|
0
|
|
|
|
|
0
|
my $value = $attrs{$_}; |
2207
|
0
|
0
|
0
|
|
|
0
|
$2 ne 'type' && $2 ne 'arrayType' |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2208
|
|
|
|
|
|
|
? $value |
2209
|
|
|
|
|
|
|
: SOAP::Utils::longname($value =~ m/^($SOAP::Constants::NSMASK?):(${SOAP::Constants::NSMASK}(?:\[[\d,]*\])*)/ |
2210
|
|
|
|
|
|
|
? ($uris{$1} || die("Unresolved prefix '$1' for attribute value '$value'\n"), $2) |
2211
|
|
|
|
|
|
|
: ($uris{''} || die("Unspecified namespace for type '$value'\n"), $value) |
2212
|
|
|
|
|
|
|
); |
2213
|
|
|
|
|
|
|
}; |
2214
|
0
|
|
|
|
|
0
|
1; |
2215
|
|
|
|
|
|
|
} |
2216
|
|
|
|
|
|
|
|| die "Unresolved prefix '$1' for attribute '$_'\n"; |
2217
|
|
|
|
|
|
|
} |
2218
|
|
|
|
|
|
|
|
2219
|
|
|
|
|
|
|
# and now check the element |
2220
|
0
|
0
|
|
|
|
0
|
my $ns = ($name =~ s/^($SOAP::Constants::NSMASK?):// ? $1 : ''); |
2221
|
0
|
0
|
0
|
|
|
0
|
$ref->[ _NAME ] = SOAP::Utils::longname( |
|
|
0
|
|
|
|
|
|
2222
|
|
|
|
|
|
|
$ns |
2223
|
|
|
|
|
|
|
? ($uris{$ns} || die "Unresolved prefix '$ns' for element '$name'\n") |
2224
|
|
|
|
|
|
|
: (defined $uris{''} ? $uris{''} : undef), |
2225
|
|
|
|
|
|
|
$name |
2226
|
|
|
|
|
|
|
); |
2227
|
|
|
|
|
|
|
|
2228
|
0
|
0
|
|
|
|
0
|
($children, $value) = (undef, $children) unless ref $children; |
2229
|
|
|
|
|
|
|
|
2230
|
0
|
|
|
|
|
0
|
return $name => ($ref->[4] = $self->decode_value( |
2231
|
|
|
|
|
|
|
[$ref->[ _NAME ], \%attrs, $children, $value] |
2232
|
|
|
|
|
|
|
)); |
2233
|
|
|
|
|
|
|
} |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
sub decode_value { |
2236
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2237
|
0
|
|
|
|
|
0
|
my($name, $attrs, $children, $value) = @{ $_[0] }; |
|
0
|
|
|
|
|
0
|
|
2238
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
# check SOAP version if applicable |
2240
|
25
|
|
0
|
25
|
|
139
|
use vars '$level'; local $level = $level || 0; |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
6938
|
|
|
0
|
|
|
|
|
0
|
|
2241
|
0
|
0
|
|
|
|
0
|
if (++$level == 1) { |
2242
|
0
|
|
|
|
|
0
|
my($namespace, $envelope) = SOAP::Utils::splitlongname($name); |
2243
|
0
|
0
|
0
|
|
|
0
|
SOAP::Lite->soapversion($namespace) if $envelope eq 'Envelope' && $namespace; |
2244
|
|
|
|
|
|
|
} |
2245
|
|
|
|
|
|
|
|
2246
|
0
|
0
|
|
|
|
0
|
if (exists $attrs->{"{$SOAP::Constants::NS_ENV}encodingStyle"}) { |
2247
|
|
|
|
|
|
|
# check encodingStyle |
2248
|
|
|
|
|
|
|
# future versions may bind deserializer to encodingStyle |
2249
|
0
|
|
|
|
|
0
|
my $encodingStyle = $attrs->{"{$SOAP::Constants::NS_ENV}encodingStyle"}; |
2250
|
|
|
|
|
|
|
# TODO - SOAP 1.2 and 1.1 have different rules about valid encodingStyle values |
2251
|
|
|
|
|
|
|
# For example, in 1.1 - any http://schemas.xmlsoap.org/soap/encoding/* |
2252
|
|
|
|
|
|
|
# value is valid |
2253
|
0
|
0
|
0
|
|
|
0
|
if (defined $encodingStyle && length($encodingStyle)) { |
2254
|
0
|
|
|
|
|
0
|
my %styles = map { $_ => undef } @SOAP::Constants::SUPPORTED_ENCODING_STYLES; |
|
0
|
|
|
|
|
0
|
|
2255
|
0
|
|
|
|
|
0
|
my $found = 0; |
2256
|
0
|
|
|
|
|
0
|
foreach my $e (split(/ +/,$encodingStyle)) { |
2257
|
0
|
0
|
|
|
|
0
|
if (exists $styles{$e}) { |
2258
|
0
|
|
|
|
|
0
|
$found ++; |
2259
|
|
|
|
|
|
|
} |
2260
|
|
|
|
|
|
|
} |
2261
|
0
|
0
|
0
|
|
|
0
|
die "Unrecognized/unsupported value of encodingStyle attribute '$encodingStyle'" |
|
|
|
0
|
|
|
|
|
2262
|
|
|
|
|
|
|
if (! $found) && !(SOAP::Lite->soapversion == 1.1 && $encodingStyle =~ /(?:^|\b)$SOAP::Constants::NS_ENC/); |
2263
|
|
|
|
|
|
|
} |
2264
|
|
|
|
|
|
|
} |
2265
|
25
|
|
|
25
|
|
352
|
use vars '$arraytype'; # type of Array element specified on Array itself |
|
25
|
|
|
|
|
59
|
|
|
25
|
|
|
|
|
5295
|
|
2266
|
|
|
|
|
|
|
# either specified with xsi:type, or or array element |
2267
|
0
|
|
|
|
|
0
|
my ($type) = grep { defined } |
|
0
|
|
|
|
|
0
|
|
2268
|
0
|
0
|
|
|
|
0
|
map($attrs->{$_}, sort grep {/^\{$SOAP::Constants::NS_XSI_ALL\}type$/o} keys %$attrs), |
2269
|
|
|
|
|
|
|
$name =~ /^\{$SOAP::Constants::NS_ENC\}/ ? $name : $arraytype; |
2270
|
0
|
|
|
|
|
0
|
local $arraytype; # it's used only for one level, we don't need it anymore |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
# $name is not used here since type should be encoded as type, not as name |
2273
|
0
|
0
|
|
|
|
0
|
my ($schema, $class) = SOAP::Utils::splitlongname($type) if $type; |
2274
|
0
|
|
0
|
|
|
0
|
my $schemaclass = defined($schema) && $self->{ _xmlschemas }->{$schema} |
2275
|
|
|
|
|
|
|
|| $self; |
2276
|
|
|
|
|
|
|
|
2277
|
0
|
0
|
|
|
|
0
|
if (! exists $_class_loaded{$schemaclass}) { |
2278
|
25
|
|
|
25
|
|
867
|
no strict qw(refs); |
|
25
|
|
|
|
|
913
|
|
|
25
|
|
|
|
|
37043
|
|
2279
|
0
|
0
|
|
|
|
0
|
if (! Class::Inspector->loaded($schemaclass) ) { |
2280
|
0
|
0
|
0
|
|
|
0
|
eval "require $schemaclass" or die $@ if not ref $schemaclass; |
2281
|
|
|
|
|
|
|
} |
2282
|
0
|
|
|
|
|
0
|
$_class_loaded{$schemaclass} = undef; |
2283
|
|
|
|
|
|
|
} |
2284
|
|
|
|
|
|
|
|
2285
|
|
|
|
|
|
|
# store schema that is used in parsed message |
2286
|
0
|
0
|
0
|
|
|
0
|
$self->{ _xmlschema } = $schema if ($schema) && $schema =~ /XMLSchema/; |
2287
|
|
|
|
|
|
|
|
2288
|
|
|
|
|
|
|
# don't use class/type if anyType/ur-type is specified on wire |
2289
|
0
|
0
|
0
|
|
|
0
|
undef $class |
2290
|
|
|
|
|
|
|
if $schemaclass->can('anyTypeValue') |
2291
|
|
|
|
|
|
|
&& $schemaclass->anyTypeValue eq $class; |
2292
|
|
|
|
|
|
|
|
2293
|
0
|
|
0
|
|
|
0
|
my $method = 'as_' . ($class || '-'); # dummy type if not defined |
2294
|
0
|
0
|
|
|
|
0
|
$class =~ s/__|\./::/g if $class; |
2295
|
|
|
|
|
|
|
|
2296
|
0
|
|
|
|
|
0
|
my $id = $attrs->{id}; |
2297
|
0
|
0
|
0
|
|
|
0
|
if (defined $id && exists $self->hrefs->{$id}) { |
|
|
0
|
|
|
|
|
|
2298
|
0
|
|
|
|
|
0
|
return $self->hrefs->{$id}; |
2299
|
|
|
|
|
|
|
} |
2300
|
|
|
|
|
|
|
elsif (exists $attrs->{href}) { |
2301
|
0
|
|
|
|
|
0
|
(my $id = delete $attrs->{href}) =~ s/^(#|cid:|uuid:)?//; |
2302
|
0
|
|
|
|
|
0
|
my $type=$1; |
2303
|
0
|
0
|
0
|
|
|
0
|
$id=uri_unescape($id) if (defined($type) and $type eq 'cid:'); |
2304
|
|
|
|
|
|
|
# convert to absolute if not internal '#' or 'cid:' |
2305
|
0
|
0
|
|
|
|
0
|
$id = $self->baselocation($id) unless $type; |
2306
|
0
|
0
|
|
|
|
0
|
return $self->hrefs->{$id} if exists $self->hrefs->{$id}; |
2307
|
|
|
|
|
|
|
# First time optimization. we don't traverse IDs unless asked for it. |
2308
|
|
|
|
|
|
|
# This is where traversing id's is delayed from before |
2309
|
|
|
|
|
|
|
# - the first time through - ids should contain a copy of the parsed XML |
2310
|
|
|
|
|
|
|
# structure! seems silly to make so many copies |
2311
|
0
|
|
|
|
|
0
|
my $ids = $self->ids; |
2312
|
0
|
0
|
|
|
|
0
|
if (ref($ids) ne 'HASH') { |
2313
|
0
|
|
|
|
|
0
|
$self->ids({}); # reset list of ids first time through |
2314
|
0
|
|
|
|
|
0
|
$self->traverse_ids($ids); |
2315
|
|
|
|
|
|
|
} |
2316
|
0
|
0
|
|
|
|
0
|
if (exists($self->ids->{$id})) { |
2317
|
0
|
|
|
|
|
0
|
my $obj = ($self->decode_object(delete($self->ids->{$id})))[1]; |
2318
|
0
|
|
|
|
|
0
|
return $self->hrefs->{$id} = $obj; |
2319
|
|
|
|
|
|
|
} |
2320
|
|
|
|
|
|
|
else { |
2321
|
0
|
|
|
|
|
0
|
die "Unresolved (wrong?) href ($id) in element '$name'\n"; |
2322
|
|
|
|
|
|
|
} |
2323
|
|
|
|
|
|
|
} |
2324
|
|
|
|
|
|
|
|
2325
|
|
|
|
|
|
|
return undef if grep { |
2326
|
0
|
0
|
|
|
|
0
|
/^$SOAP::Constants::NS_XSI_NILS$/ && do { |
|
0
|
0
|
|
|
|
0
|
|
2327
|
0
|
|
0
|
|
|
0
|
my $class = $self->xmlschemas->{ $1 || $2 }; |
2328
|
0
|
0
|
|
|
|
0
|
eval "require $class" or die @$;; |
2329
|
0
|
|
|
|
|
0
|
$class->as_undef($attrs->{$_}) |
2330
|
|
|
|
|
|
|
} |
2331
|
|
|
|
|
|
|
} keys %$attrs; |
2332
|
|
|
|
|
|
|
|
2333
|
|
|
|
|
|
|
# try to handle with typecasting |
2334
|
0
|
|
|
|
|
0
|
my $res = $self->typecast($value, $name, $attrs, $children, $type); |
2335
|
0
|
0
|
|
|
|
0
|
return $res if defined $res; |
2336
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
# ok, continue with others |
2338
|
0
|
0
|
0
|
|
|
0
|
if (exists $attrs->{"{$SOAP::Constants::NS_ENC}arrayType"}) { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
2339
|
0
|
|
|
|
|
0
|
my $res = []; |
2340
|
0
|
0
|
|
|
|
0
|
$self->hrefs->{$id} = $res if defined $id; |
2341
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
# check for arrayType which could be [1], [,2][5] or [] |
2343
|
|
|
|
|
|
|
# [,][1] will NOT be allowed right now (multidimensional sparse array) |
2344
|
0
|
0
|
|
|
|
0
|
my($type, $multisize) = $attrs->{"{$SOAP::Constants::NS_ENC}arrayType"} |
2345
|
|
|
|
|
|
|
=~ /^(.+)\[(\d*(?:,\d+)*)\](?:\[(?:\d+(?:,\d+)*)\])*$/ |
2346
|
0
|
|
|
|
|
0
|
or die qq!Unrecognized/unsupported format of arrayType attribute '@{[$attrs->{"{$SOAP::Constants::NS_ENC}arrayType"}]}'\n!; |
2347
|
|
|
|
|
|
|
|
2348
|
0
|
0
|
|
|
|
0
|
my @dimensions = map { $_ || undef } split /,/, $multisize; |
|
0
|
|
|
|
|
0
|
|
2349
|
0
|
|
|
|
|
0
|
my $size = 1; |
2350
|
0
|
|
0
|
|
|
0
|
foreach (@dimensions) { $size *= $_ || 0 } |
|
0
|
|
|
|
|
0
|
|
2351
|
|
|
|
|
|
|
|
2352
|
|
|
|
|
|
|
# TODO ähm, shouldn't this local be my? |
2353
|
0
|
|
|
|
|
0
|
local $arraytype = $type; |
2354
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
# multidimensional |
2356
|
0
|
0
|
|
|
|
0
|
if ($multisize =~ /,/) { |
2357
|
0
|
|
|
|
|
0
|
@$res = splitarray( |
2358
|
|
|
|
|
|
|
[@dimensions], |
2359
|
0
|
0
|
|
|
|
0
|
[map { scalar(($self->decode_object($_))[1]) } @{$children || []}] |
|
0
|
|
|
|
|
0
|
|
2360
|
|
|
|
|
|
|
); |
2361
|
|
|
|
|
|
|
} |
2362
|
|
|
|
|
|
|
# normal |
2363
|
|
|
|
|
|
|
else { |
2364
|
0
|
0
|
|
|
|
0
|
@$res = map { scalar(($self->decode_object($_))[1]) } @{$children || []}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2365
|
|
|
|
|
|
|
} |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
# sparse (position) |
2368
|
0
|
0
|
0
|
|
|
0
|
if (ref $children && exists SOAP::Utils::o_lattr($children->[0])->{"{$SOAP::Constants::NS_ENC}position"}) { |
2369
|
0
|
|
|
|
|
0
|
my @new; |
2370
|
0
|
|
|
|
|
0
|
for (my $pos = 0; $pos < @$children; $pos++) { |
2371
|
|
|
|
|
|
|
# TBD implement position in multidimensional array |
2372
|
0
|
0
|
|
|
|
0
|
my($position) = SOAP::Utils::o_lattr($children->[$pos])->{"{$SOAP::Constants::NS_ENC}position"} =~ /^\[(\d+)\]$/ |
2373
|
|
|
|
|
|
|
or die "Position must be specified for all elements of sparse array\n"; |
2374
|
0
|
|
|
|
|
0
|
$new[$position] = $res->[$pos]; |
2375
|
|
|
|
|
|
|
} |
2376
|
0
|
|
|
|
|
0
|
@$res = @new; |
2377
|
|
|
|
|
|
|
} |
2378
|
|
|
|
|
|
|
|
2379
|
|
|
|
|
|
|
# partially transmitted (offset) |
2380
|
|
|
|
|
|
|
# TBD implement offset in multidimensional array |
2381
|
0
|
0
|
|
|
|
0
|
my($offset) = $attrs->{"{$SOAP::Constants::NS_ENC}offset"} =~ /^\[(\d+)\]$/ |
2382
|
|
|
|
|
|
|
if exists $attrs->{"{$SOAP::Constants::NS_ENC}offset"}; |
2383
|
0
|
0
|
|
|
|
0
|
unshift(@$res, (undef) x $offset) if $offset; |
2384
|
|
|
|
|
|
|
|
2385
|
0
|
0
|
0
|
|
|
0
|
die "Too many elements in array. @{[scalar@$res]} instead of claimed $multisize ($size)\n" |
|
0
|
|
|
|
|
0
|
|
2386
|
|
|
|
|
|
|
if $multisize && $size < @$res; |
2387
|
|
|
|
|
|
|
|
2388
|
|
|
|
|
|
|
# extend the array if number of elements is specified |
2389
|
0
|
0
|
0
|
|
|
0
|
$#$res = $dimensions[0]-1 if defined $dimensions[0] && @$res < $dimensions[0]; |
2390
|
|
|
|
|
|
|
|
2391
|
0
|
0
|
0
|
|
|
0
|
return defined $class && $class ne 'Array' ? bless($res => $class) : $res; |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
} |
2394
|
|
|
|
|
|
|
elsif ($name =~ /^\{$SOAP::Constants::NS_ENC\}Struct$/ |
2395
|
|
|
|
|
|
|
|| !$schemaclass->can($method) |
2396
|
|
|
|
|
|
|
&& (ref $children || defined $class && $value =~ /^\s*$/)) { |
2397
|
0
|
|
|
|
|
0
|
my $res = {}; |
2398
|
0
|
0
|
|
|
|
0
|
$self->hrefs->{$id} = $res if defined $id; |
2399
|
|
|
|
|
|
|
|
2400
|
|
|
|
|
|
|
# Patch code introduced in 0.65 - deserializes array properly |
2401
|
|
|
|
|
|
|
# Decode each element of the struct. |
2402
|
0
|
|
|
|
|
0
|
my %child_count_of = (); |
2403
|
0
|
0
|
|
|
|
0
|
foreach my $child (@{$children || []}) { |
|
0
|
|
|
|
|
0
|
|
2404
|
0
|
|
|
|
|
0
|
my ($child_name, $child_value) = $self->decode_object($child); |
2405
|
|
|
|
|
|
|
# Store the decoded element in the struct. If the element name is |
2406
|
|
|
|
|
|
|
# repeated, replace the previous scalar value with a new array |
2407
|
|
|
|
|
|
|
# containing both values. |
2408
|
0
|
0
|
|
|
|
0
|
if (not $child_count_of{$child_name}) { |
|
|
0
|
|
|
|
|
|
2409
|
|
|
|
|
|
|
# first time to see this value: use scalar |
2410
|
0
|
|
|
|
|
0
|
$res->{$child_name} = $child_value; |
2411
|
|
|
|
|
|
|
} |
2412
|
|
|
|
|
|
|
elsif ($child_count_of{$child_name} == 1) { |
2413
|
|
|
|
|
|
|
# second time to see this value: convert scalar to array |
2414
|
0
|
|
|
|
|
0
|
$res->{$child_name} = [ $res->{$child_name}, $child_value ]; |
2415
|
|
|
|
|
|
|
} |
2416
|
|
|
|
|
|
|
else { |
2417
|
|
|
|
|
|
|
# already have an array: append to it |
2418
|
0
|
|
|
|
|
0
|
push @{$res->{$child_name}}, $child_value; |
|
0
|
|
|
|
|
0
|
|
2419
|
|
|
|
|
|
|
} |
2420
|
0
|
|
|
|
|
0
|
$child_count_of{$child_name}++; |
2421
|
|
|
|
|
|
|
} |
2422
|
|
|
|
|
|
|
# End patch code |
2423
|
|
|
|
|
|
|
|
2424
|
0
|
0
|
0
|
|
|
0
|
return defined $class && $class ne 'SOAPStruct' ? bless($res => $class) : $res; |
2425
|
|
|
|
|
|
|
} |
2426
|
|
|
|
|
|
|
else { |
2427
|
0
|
|
|
|
|
0
|
my $res; |
2428
|
0
|
0
|
|
|
|
0
|
if (my $method_ref = $schemaclass->can($method)) { |
2429
|
0
|
|
|
|
|
0
|
$res = $method_ref->($self, $value, $name, $attrs, $children, $type); |
2430
|
|
|
|
|
|
|
} |
2431
|
|
|
|
|
|
|
else { |
2432
|
0
|
|
|
|
|
0
|
$res = $self->typecast($value, $name, $attrs, $children, $type); |
2433
|
0
|
0
|
|
|
|
0
|
$res = $class ? die "Unrecognized type '$type'\n" : $value |
|
|
0
|
|
|
|
|
|
2434
|
|
|
|
|
|
|
unless defined $res; |
2435
|
|
|
|
|
|
|
} |
2436
|
0
|
0
|
|
|
|
0
|
$self->hrefs->{$id} = $res if defined $id; |
2437
|
0
|
|
|
|
|
0
|
return $res; |
2438
|
|
|
|
|
|
|
} |
2439
|
|
|
|
|
|
|
} |
2440
|
|
|
|
|
|
|
|
2441
|
|
|
|
|
|
|
sub splitarray { |
2442
|
0
|
|
|
0
|
|
0
|
my @sizes = @{+shift}; |
|
0
|
|
|
|
|
0
|
|
2443
|
0
|
|
|
|
|
0
|
my $size = shift @sizes; |
2444
|
0
|
|
|
|
|
0
|
my $array = shift; |
2445
|
|
|
|
|
|
|
|
2446
|
0
|
0
|
|
|
|
0
|
return splice(@$array, 0, $size) unless @sizes; |
2447
|
0
|
|
|
|
|
0
|
my @array = (); |
2448
|
0
|
|
0
|
|
|
0
|
push @array, [ |
|
|
|
0
|
|
|
|
|
2449
|
|
|
|
|
|
|
splitarray([@sizes], $array) |
2450
|
|
|
|
|
|
|
] while @$array && (!defined $size || $size--); |
2451
|
0
|
|
|
|
|
0
|
return @array; |
2452
|
|
|
|
|
|
|
} |
2453
|
|
|
|
|
|
|
|
2454
|
0
|
|
|
0
|
|
0
|
sub typecast { } # typecast is called for both objects AND scalar types |
2455
|
|
|
|
|
|
|
# check ref of the second parameter (first is the object) |
2456
|
|
|
|
|
|
|
# return undef if you don't want to handle it |
2457
|
|
|
|
|
|
|
|
2458
|
|
|
|
|
|
|
# ====================================================================== |
2459
|
|
|
|
|
|
|
|
2460
|
|
|
|
|
|
|
package SOAP::Client; |
2461
|
|
|
|
|
|
|
|
2462
|
|
|
|
|
|
|
|
2463
|
25
|
|
|
25
|
|
192
|
use SOAP::Lite::Utils; |
|
25
|
|
|
|
|
41
|
|
|
25
|
|
|
|
|
234
|
|
2464
|
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
$VERSION = $SOAP::Lite::VERSION; |
2466
|
|
|
|
|
|
|
sub BEGIN { |
2467
|
25
|
|
|
25
|
|
128
|
__PACKAGE__->__mk_accessors(qw(endpoint code message |
2468
|
|
|
|
|
|
|
is_success status options)); |
2469
|
|
|
|
|
|
|
} |
2470
|
|
|
|
|
|
|
|
2471
|
|
|
|
|
|
|
# ====================================================================== |
2472
|
|
|
|
|
|
|
|
2473
|
|
|
|
|
|
|
package SOAP::Server::Object; |
2474
|
|
|
|
|
|
|
|
2475
|
|
|
|
|
|
|
sub gen_id; *gen_id = \&SOAP::Serializer::gen_id; |
2476
|
|
|
|
|
|
|
|
2477
|
|
|
|
|
|
|
my %alive; |
2478
|
|
|
|
|
|
|
my %objects; |
2479
|
|
|
|
|
|
|
|
2480
|
|
|
|
|
|
|
sub objects_by_reference { |
2481
|
0
|
|
|
0
|
|
0
|
shift; |
2482
|
0
|
|
|
|
|
0
|
while (@_) { |
2483
|
|
|
|
|
|
|
@alive{shift()} = ref $_[0] |
2484
|
|
|
|
|
|
|
? shift |
2485
|
|
|
|
|
|
|
: sub { |
2486
|
0
|
0
|
|
0
|
|
0
|
$_[1]-$_[$_[5] ? 5 : 4] > $SOAP::Constants::OBJS_BY_REF_KEEPALIVE |
2487
|
|
|
|
|
|
|
} |
2488
|
0
|
0
|
|
|
|
0
|
} |
2489
|
0
|
|
|
|
|
0
|
keys %alive; |
2490
|
|
|
|
|
|
|
} |
2491
|
|
|
|
|
|
|
|
2492
|
|
|
|
|
|
|
sub reference { |
2493
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2494
|
0
|
|
|
|
|
0
|
my $stamp = time; |
2495
|
0
|
|
|
|
|
0
|
my $object = shift; |
2496
|
0
|
|
|
|
|
0
|
my $id = $stamp . $self->gen_id($object); |
2497
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
# this is code for garbage collection |
2499
|
0
|
|
|
|
|
0
|
my $time = time; |
2500
|
0
|
|
|
|
|
0
|
my $type = ref $object; |
2501
|
0
|
|
|
|
|
0
|
my @objects = grep { $objects{$_}->[1] eq $type } keys %objects; |
|
0
|
|
|
|
|
0
|
|
2502
|
0
|
|
|
|
|
0
|
for (grep { $alive{$type}->(scalar @objects, $time, @{$objects{$_}}) } @objects) { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2503
|
0
|
|
|
|
|
0
|
delete $objects{$_}; |
2504
|
|
|
|
|
|
|
} |
2505
|
|
|
|
|
|
|
|
2506
|
0
|
|
|
|
|
0
|
$objects{$id} = [$object, $type, $stamp]; |
2507
|
0
|
|
|
|
|
0
|
bless { id => $id } => ref $object; |
2508
|
|
|
|
|
|
|
} |
2509
|
|
|
|
|
|
|
|
2510
|
|
|
|
|
|
|
sub references { |
2511
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2512
|
0
|
0
|
|
|
|
0
|
return @_ unless %alive; # small optimization |
2513
|
0
|
0
|
0
|
|
|
0
|
return map { |
2514
|
0
|
|
|
|
|
0
|
ref($_) && exists $alive{ref $_} |
2515
|
|
|
|
|
|
|
? $self->reference($_) |
2516
|
|
|
|
|
|
|
: $_ |
2517
|
|
|
|
|
|
|
} @_; |
2518
|
|
|
|
|
|
|
} |
2519
|
|
|
|
|
|
|
|
2520
|
|
|
|
|
|
|
sub object { |
2521
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2522
|
0
|
|
0
|
|
|
0
|
my $class = ref($self) || $self; |
2523
|
0
|
|
|
|
|
0
|
my $object = shift; |
2524
|
0
|
0
|
0
|
|
|
0
|
return $object unless ref($object) && $alive{ref $object} && exists $object->{id}; |
|
|
|
0
|
|
|
|
|
2525
|
|
|
|
|
|
|
|
2526
|
0
|
|
|
|
|
0
|
my $reference = $objects{$object->{id}}; |
2527
|
0
|
0
|
|
|
|
0
|
die "Object with specified id couldn't be found\n" unless ref $reference->[0]; |
2528
|
|
|
|
|
|
|
|
2529
|
0
|
|
|
|
|
0
|
$reference->[3] = time; # last access time |
2530
|
0
|
|
|
|
|
0
|
return $reference->[0]; # reference to actual object |
2531
|
|
|
|
|
|
|
} |
2532
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
sub objects { |
2534
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2535
|
0
|
0
|
|
|
|
0
|
return @_ unless %alive; # small optimization |
2536
|
0
|
0
|
0
|
|
|
0
|
return map { |
2537
|
0
|
|
|
|
|
0
|
ref($_) && exists $alive{ref $_} && exists $_->{id} |
2538
|
|
|
|
|
|
|
? $self->object($_) |
2539
|
|
|
|
|
|
|
: $_ |
2540
|
|
|
|
|
|
|
} @_; |
2541
|
|
|
|
|
|
|
} |
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
# ====================================================================== |
2544
|
|
|
|
|
|
|
|
2545
|
|
|
|
|
|
|
package SOAP::Server::Parameters; |
2546
|
|
|
|
|
|
|
|
2547
|
|
|
|
|
|
|
sub byNameOrOrder { |
2548
|
0
|
0
|
|
0
|
|
0
|
unless (UNIVERSAL::isa($_[-1] => 'SOAP::SOM')) { |
2549
|
0
|
0
|
|
|
|
0
|
warn "Last parameter is expected to be envelope\n" if $^W; |
2550
|
0
|
|
|
|
|
0
|
pop; |
2551
|
0
|
|
|
|
|
0
|
return @_; |
2552
|
|
|
|
|
|
|
} |
2553
|
0
|
|
|
|
|
0
|
my $params = pop->method; |
2554
|
0
|
|
|
|
|
0
|
my @mandatory = ref $_[0] eq 'ARRAY' |
2555
|
0
|
0
|
|
|
|
0
|
? @{shift()} |
2556
|
|
|
|
|
|
|
: die "list of parameters expected as the first parameter for byName"; |
2557
|
0
|
|
|
|
|
0
|
my $byname = 0; |
2558
|
0
|
|
|
|
|
0
|
my @res = map { $byname += exists $params->{$_}; $params->{$_} } @mandatory; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2559
|
0
|
0
|
|
|
|
0
|
return $byname |
2560
|
|
|
|
|
|
|
? @res |
2561
|
|
|
|
|
|
|
: @_; |
2562
|
|
|
|
|
|
|
} |
2563
|
|
|
|
|
|
|
|
2564
|
|
|
|
|
|
|
sub byName { |
2565
|
0
|
0
|
|
0
|
|
0
|
unless (UNIVERSAL::isa($_[-1] => 'SOAP::SOM')) { |
2566
|
0
|
0
|
|
|
|
0
|
warn "Last parameter is expected to be envelope\n" if $^W; |
2567
|
0
|
|
|
|
|
0
|
pop; |
2568
|
0
|
|
|
|
|
0
|
return @_; |
2569
|
|
|
|
|
|
|
} |
2570
|
0
|
0
|
|
|
|
0
|
return @{pop->method}{ref $_[0] eq 'ARRAY' ? @{shift()} : die "list of parameters expected as the first parameter for byName"}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2571
|
|
|
|
|
|
|
} |
2572
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
# ====================================================================== |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
package SOAP::Server; |
2576
|
|
|
|
|
|
|
|
2577
|
25
|
|
|
25
|
|
776
|
use Carp (); |
|
25
|
|
|
|
|
40
|
|
|
25
|
|
|
|
|
531
|
|
2578
|
25
|
|
|
25
|
|
134
|
use Scalar::Util qw(weaken); |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
7657
|
|
2579
|
1
|
|
|
1
|
|
2
|
sub DESTROY { SOAP::Trace::objects('()') } |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
sub initialize { |
2582
|
|
|
|
|
|
|
return ( |
2583
|
|
|
|
|
|
|
packager => SOAP::Packager::MIME->new, |
2584
|
|
|
|
|
|
|
transport => SOAP::Transport->new, |
2585
|
|
|
|
|
|
|
serializer => SOAP::Serializer->new, |
2586
|
|
|
|
|
|
|
deserializer => SOAP::Deserializer->new, |
2587
|
0
|
|
|
0
|
|
0
|
on_action => sub { ; }, |
2588
|
|
|
|
|
|
|
on_dispatch => sub { |
2589
|
0
|
|
|
0
|
|
0
|
return; |
2590
|
|
|
|
|
|
|
}, |
2591
|
1
|
|
|
1
|
|
5
|
); |
2592
|
|
|
|
|
|
|
} |
2593
|
|
|
|
|
|
|
|
2594
|
|
|
|
|
|
|
sub new { |
2595
|
13
|
|
|
13
|
|
13
|
my $self = shift; |
2596
|
13
|
100
|
|
|
|
28
|
return $self if ref $self; |
2597
|
|
|
|
|
|
|
|
2598
|
1
|
50
|
|
|
|
3
|
unless (ref $self) { |
2599
|
1
|
|
|
|
|
3
|
my $class = $self; |
2600
|
1
|
|
|
|
|
2
|
my(@params, @methods); |
2601
|
|
|
|
|
|
|
|
2602
|
1
|
|
|
|
|
3
|
while (@_) { |
2603
|
0
|
|
|
|
|
0
|
my($method, $params) = splice(@_,0,2); |
2604
|
0
|
0
|
0
|
|
|
0
|
$class->can($method) |
2605
|
|
|
|
|
|
|
? push(@methods, $method, $params) |
2606
|
|
|
|
|
|
|
: $^W && Carp::carp "Unrecognized parameter '$method' in new()"; |
2607
|
|
|
|
|
|
|
} |
2608
|
|
|
|
|
|
|
|
2609
|
1
|
|
|
|
|
8
|
$self = bless { |
2610
|
|
|
|
|
|
|
_dispatch_to => [], |
2611
|
|
|
|
|
|
|
_dispatch_with => {}, |
2612
|
|
|
|
|
|
|
_dispatched => [], |
2613
|
|
|
|
|
|
|
_action => '', |
2614
|
|
|
|
|
|
|
_options => {}, |
2615
|
|
|
|
|
|
|
} => $class; |
2616
|
1
|
|
|
|
|
4
|
unshift(@methods, $self->initialize); |
2617
|
25
|
|
|
25
|
|
132
|
no strict qw(refs); |
|
25
|
|
|
|
|
40
|
|
|
25
|
|
|
|
|
2548
|
|
2618
|
1
|
|
|
|
|
5
|
while (@methods) { |
2619
|
6
|
|
|
|
|
11
|
my($method, $params) = splice(@methods,0,2); |
2620
|
6
|
50
|
|
|
|
24
|
$self->$method(ref $params eq 'ARRAY' ? @$params : $params) |
2621
|
|
|
|
|
|
|
} |
2622
|
1
|
|
|
|
|
3
|
SOAP::Trace::objects('()'); |
2623
|
|
|
|
|
|
|
} |
2624
|
|
|
|
|
|
|
|
2625
|
1
|
50
|
33
|
|
|
8
|
Carp::carp "Odd (wrong?) number of parameters in new()" |
2626
|
|
|
|
|
|
|
if $^W && (@_ & 1); |
2627
|
|
|
|
|
|
|
|
2628
|
25
|
|
|
25
|
|
114
|
no strict qw(refs); |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
4885
|
|
2629
|
1
|
|
|
|
|
4
|
while (@_) { |
2630
|
0
|
|
|
|
|
0
|
my($method, $params) = splice(@_,0,2); |
2631
|
0
|
0
|
0
|
|
|
0
|
$self->can($method) |
|
|
0
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
? $self->$method(ref $params eq 'ARRAY' ? @$params : $params) |
2633
|
|
|
|
|
|
|
: $^W && Carp::carp "Unrecognized parameter '$method' in new()" |
2634
|
|
|
|
|
|
|
} |
2635
|
|
|
|
|
|
|
|
2636
|
1
|
|
|
|
|
3
|
return $self; |
2637
|
|
|
|
|
|
|
} |
2638
|
|
|
|
|
|
|
|
2639
|
|
|
|
|
|
|
sub init_context { |
2640
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
2641
|
1
|
|
|
|
|
2
|
$self->{'_deserializer'}->{'_context'} = $self; |
2642
|
|
|
|
|
|
|
# weaken circular reference to avoid a memory hole |
2643
|
1
|
|
|
|
|
6
|
weaken($self->{'_deserializer'}->{'_context'}); |
2644
|
|
|
|
|
|
|
|
2645
|
1
|
|
|
|
|
1
|
$self->{'_serializer'}->{'_context'} = $self; |
2646
|
|
|
|
|
|
|
# weaken circular reference to avoid a memory hole |
2647
|
1
|
|
|
|
|
4
|
weaken($self->{'_serializer'}->{'_context'}); |
2648
|
|
|
|
|
|
|
} |
2649
|
|
|
|
|
|
|
|
2650
|
|
|
|
|
|
|
sub BEGIN { |
2651
|
25
|
|
|
25
|
|
158
|
no strict 'refs'; |
|
25
|
|
|
|
|
29
|
|
|
25
|
|
|
|
|
8701
|
|
2652
|
25
|
|
|
25
|
|
67
|
for my $method (qw(serializer deserializer transport)) { |
2653
|
75
|
|
|
|
|
127
|
my $field = '_' . $method; |
2654
|
|
|
|
|
|
|
*$method = sub { |
2655
|
6
|
|
|
6
|
|
9
|
my $self = shift->new(); |
2656
|
6
|
100
|
|
|
|
12
|
if (@_) { |
2657
|
3
|
|
|
|
|
6
|
my $context = $self->{$field}->{'_context'}; # save the old context |
2658
|
3
|
|
|
|
|
4
|
$self->{$field} = shift; |
2659
|
3
|
|
|
|
|
10
|
$self->{$field}->{'_context'} = $context; # restore the old context |
2660
|
3
|
|
|
|
|
5
|
return $self; |
2661
|
|
|
|
|
|
|
} |
2662
|
|
|
|
|
|
|
else { |
2663
|
3
|
|
|
|
|
14
|
return $self->{$field}; |
2664
|
|
|
|
|
|
|
} |
2665
|
|
|
|
|
|
|
} |
2666
|
75
|
|
|
|
|
2176
|
} |
2667
|
|
|
|
|
|
|
|
2668
|
25
|
|
|
|
|
49
|
for my $method (qw(action myuri options dispatch_with packager)) { |
2669
|
125
|
|
|
|
|
155
|
my $field = '_' . $method; |
2670
|
|
|
|
|
|
|
*$method = sub { |
2671
|
4
|
|
|
4
|
|
12
|
my $self = shift->new(); |
2672
|
|
|
|
|
|
|
(@_) |
2673
|
4
|
100
|
|
|
|
25
|
? do { |
2674
|
1
|
|
|
|
|
6
|
$self->{$field} = shift; |
2675
|
1
|
|
|
|
|
3
|
return $self; |
2676
|
|
|
|
|
|
|
} |
2677
|
|
|
|
|
|
|
: return $self->{$field}; |
2678
|
|
|
|
|
|
|
} |
2679
|
125
|
|
|
|
|
1392
|
} |
2680
|
25
|
|
|
|
|
777
|
for my $method (qw(on_action on_dispatch)) { |
2681
|
50
|
|
|
|
|
87
|
my $field = '_' . $method; |
2682
|
|
|
|
|
|
|
*$method = sub { |
2683
|
2
|
|
|
2
|
|
3
|
my $self = shift->new; |
2684
|
|
|
|
|
|
|
# my $self = shift; |
2685
|
2
|
50
|
|
|
|
5
|
return $self->{$field} unless @_; |
2686
|
2
|
|
|
|
|
2
|
local $@; |
2687
|
|
|
|
|
|
|
# commented out because that 'eval' was unsecure |
2688
|
|
|
|
|
|
|
# > ref $_[0] eq 'CODE' ? shift : eval shift; |
2689
|
|
|
|
|
|
|
# Am I paranoid enough? |
2690
|
2
|
|
|
|
|
4
|
$self->{$field} = shift; |
2691
|
2
|
50
|
|
|
|
3
|
Carp::croak $@ if $@; |
2692
|
2
|
50
|
|
|
|
10
|
Carp::croak "$method() expects subroutine (CODE) or string that evaluates into subroutine (CODE)" |
2693
|
|
|
|
|
|
|
unless ref $self->{$field} eq 'CODE'; |
2694
|
2
|
|
|
|
|
4
|
return $self; |
2695
|
|
|
|
|
|
|
} |
2696
|
50
|
|
|
|
|
315
|
} |
2697
|
|
|
|
|
|
|
|
2698
|
|
|
|
|
|
|
# __PACKAGE__->__mk_accessors( qw(dispatch_to) ); |
2699
|
25
|
|
|
|
|
38
|
for my $method (qw(dispatch_to)) { |
2700
|
25
|
|
|
|
|
45
|
my $field = '_' . $method; |
2701
|
|
|
|
|
|
|
*$method = sub { |
2702
|
1
|
|
|
1
|
|
68
|
my $self = shift->new; |
2703
|
|
|
|
|
|
|
# my $self = shift; |
2704
|
|
|
|
|
|
|
(@_) |
2705
|
0
|
|
|
|
|
0
|
? do { |
2706
|
1
|
|
|
|
|
3
|
$self->{$field} = [@_]; |
2707
|
1
|
|
|
|
|
2
|
return $self; |
2708
|
|
|
|
|
|
|
} |
2709
|
1
|
50
|
|
|
|
4
|
: return @{ $self->{$field} }; |
2710
|
|
|
|
|
|
|
} |
2711
|
25
|
|
|
|
|
14200
|
} |
2712
|
|
|
|
|
|
|
} |
2713
|
|
|
|
|
|
|
|
2714
|
|
|
|
|
|
|
sub objects_by_reference { |
2715
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2716
|
0
|
0
|
|
|
|
0
|
$self = $self->new() if not ref $self; |
2717
|
|
|
|
|
|
|
@_ |
2718
|
0
|
0
|
|
|
|
0
|
? (SOAP::Server::Object->objects_by_reference(@_), return $self) |
2719
|
|
|
|
|
|
|
: SOAP::Server::Object->objects_by_reference; |
2720
|
|
|
|
|
|
|
} |
2721
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
sub dispatched { |
2723
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2724
|
0
|
0
|
|
|
|
0
|
$self = $self->new() if not ref $self; |
2725
|
|
|
|
|
|
|
@_ |
2726
|
0
|
|
|
|
|
0
|
? (push(@{$self->{_dispatched}}, @_), return $self) |
|
0
|
|
|
|
|
0
|
|
2727
|
0
|
0
|
|
|
|
0
|
: return @{$self->{_dispatched}}; |
2728
|
|
|
|
|
|
|
} |
2729
|
|
|
|
|
|
|
|
2730
|
|
|
|
|
|
|
sub find_target { |
2731
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
2732
|
0
|
|
|
|
|
0
|
my $request = shift; |
2733
|
|
|
|
|
|
|
|
2734
|
|
|
|
|
|
|
# try to find URI/method from on_dispatch call first |
2735
|
0
|
|
|
|
|
0
|
my($method_uri, $method_name) = $self->on_dispatch->($request); |
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
# if nothing there, then get it from envelope itself |
2738
|
0
|
|
|
|
|
0
|
$request->match((ref $request)->method); |
2739
|
0
|
0
|
0
|
|
|
0
|
($method_uri, $method_name) = ($request->namespaceuriof || '', $request->dataof->name) |
2740
|
|
|
|
|
|
|
unless $method_name; |
2741
|
|
|
|
|
|
|
|
2742
|
0
|
|
|
|
|
0
|
$self->on_action->(my $action = $self->action, $method_uri, $method_name); |
2743
|
|
|
|
|
|
|
|
2744
|
|
|
|
|
|
|
# check to avoid security vulnerability: Protected->Unprotected::method(@parameters) |
2745
|
|
|
|
|
|
|
# see for more details: http://www.phrack.org/phrack/58/p58-0x09 |
2746
|
0
|
0
|
|
|
|
0
|
die "Denied access to method ($method_name)\n" unless $method_name =~ /^\w+$/; |
2747
|
|
|
|
|
|
|
|
2748
|
0
|
|
|
|
|
0
|
my ($class, $static); |
2749
|
|
|
|
|
|
|
# try to bind directly |
2750
|
0
|
0
|
0
|
|
|
0
|
if (defined($class = $self->dispatch_with->{$method_uri} |
2751
|
|
|
|
|
|
|
|| $self->dispatch_with->{$action || ''} |
2752
|
|
|
|
|
|
|
|| (defined($action) && $action =~ /^"(.+)"$/ |
2753
|
|
|
|
|
|
|
? $self->dispatch_with->{$1} |
2754
|
|
|
|
|
|
|
: undef))) { |
2755
|
|
|
|
|
|
|
# return object, nothing else to do here |
2756
|
0
|
0
|
|
|
|
0
|
return ($class, $method_uri, $method_name) if ref $class; |
2757
|
0
|
|
|
|
|
0
|
$static = 1; |
2758
|
|
|
|
|
|
|
} |
2759
|
|
|
|
|
|
|
else { |
2760
|
0
|
0
|
|
|
|
0
|
die "URI path shall map to class" unless defined ($class = URI->new($method_uri)->path); |
2761
|
|
|
|
|
|
|
|
2762
|
0
|
|
|
|
|
0
|
for ($class) { s!^/|/$!!g; s!/!::!g; s/^$/main/; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2763
|
0
|
0
|
|
|
|
0
|
die "Failed to access class ($class)" unless $class =~ /^(\w[\w:]*)$/; |
2764
|
|
|
|
|
|
|
|
2765
|
0
|
|
|
|
|
0
|
my $fullname = "$class\::$method_name"; |
2766
|
0
|
|
|
|
|
0
|
foreach ($self->dispatch_to) { |
2767
|
0
|
0
|
|
|
|
0
|
return ($_, $method_uri, $method_name) if ref eq $class; # $OBJECT |
2768
|
0
|
0
|
|
|
|
0
|
next if ref; # skip other objects |
2769
|
|
|
|
|
|
|
# will ignore errors, because it may complain on |
2770
|
|
|
|
|
|
|
# d:\foo\bar, which is PATH and not regexp |
2771
|
0
|
|
|
|
|
0
|
eval { |
2772
|
0
|
|
0
|
|
|
0
|
$static ||= $class =~ /^$_$/ # MODULE |
|
|
|
0
|
|
|
|
|
2773
|
|
|
|
|
|
|
|| $fullname =~ /^$_$/ # MODULE::method |
2774
|
|
|
|
|
|
|
|| $method_name =~ /^$_$/ && ($class eq 'main'); # method ('main' assumed) |
2775
|
|
|
|
|
|
|
}; |
2776
|
|
|
|
|
|
|
} |
2777
|
|
|
|
|
|
|
} |
2778
|
|
|
|
|
|
|
|
2779
|
25
|
|
|
25
|
|
154
|
no strict 'refs'; |
|
25
|
|
|
|
|
38
|
|
|
25
|
|
|
|
|
15621
|
|
2780
|
|
|
|
|
|
|
|
2781
|
|
|
|
|
|
|
# TODO - sort this mess out: |
2782
|
|
|
|
|
|
|
# The task is to test whether the class in question has already been loaded. |
2783
|
|
|
|
|
|
|
# |
2784
|
|
|
|
|
|
|
# SOAP::Lite 0.60: |
2785
|
|
|
|
|
|
|
# unless (defined %{"${class}::"}) { |
2786
|
|
|
|
|
|
|
# Patch to SOAP::Lite 0.60: |
2787
|
|
|
|
|
|
|
# The following patch does not work for packages defined within a BEGIN block |
2788
|
|
|
|
|
|
|
# unless (exists($INC{join '/', split /::/, $class.'.pm'})) { |
2789
|
|
|
|
|
|
|
# Combination of 0.60 and patch did not work reliably, either. |
2790
|
|
|
|
|
|
|
# |
2791
|
|
|
|
|
|
|
# Now we do the following: Check whether the class is main (always loaded) |
2792
|
|
|
|
|
|
|
# or the class implements the method in question |
2793
|
|
|
|
|
|
|
# or the package exists as file in %INC. |
2794
|
|
|
|
|
|
|
# |
2795
|
|
|
|
|
|
|
# This is still sort of a hack - but I don't know anything better |
2796
|
|
|
|
|
|
|
# If you have some idea, please help me out... |
2797
|
|
|
|
|
|
|
# |
2798
|
0
|
0
|
0
|
|
|
0
|
unless (($class eq 'main') || $class->can($method_name) |
|
|
|
0
|
|
|
|
|
2799
|
|
|
|
|
|
|
|| exists($INC{join '/', split /::/, $class . '.pm'})) { |
2800
|
|
|
|
|
|
|
|
2801
|
|
|
|
|
|
|
# allow all for static and only specified path for dynamic bindings |
2802
|
0
|
0
|
|
|
|
0
|
local @INC = (($static ? @INC : ()), grep {!ref && m![/\\.]!} $self->dispatch_to()); |
|
0
|
0
|
|
|
|
0
|
|
2803
|
0
|
|
|
|
|
0
|
eval 'local $^W; ' . "require $class"; |
2804
|
0
|
0
|
|
|
|
0
|
die "Failed to access class ($class): $@" if $@; |
2805
|
0
|
0
|
|
|
|
0
|
$self->dispatched($class) unless $static; |
2806
|
|
|
|
|
|
|
} |
2807
|
|
|
|
|
|
|
|
2808
|
0
|
|
|
|
|
0
|
die "Denied access to method ($method_name) in class ($class)" |
2809
|
0
|
0
|
0
|
|
|
0
|
unless $static || grep {/^$class$/} $self->dispatched; |
2810
|
|
|
|
|
|
|
|
2811
|
0
|
|
|
|
|
0
|
return ($class, $method_uri, $method_name); |
2812
|
|
|
|
|
|
|
} |
2813
|
|
|
|
|
|
|
|
2814
|
|
|
|
|
|
|
sub handle { |
2815
|
1
|
|
|
1
|
|
12
|
SOAP::Trace::trace('()'); |
2816
|
1
|
|
|
|
|
2
|
my $self = shift; |
2817
|
1
|
50
|
|
|
|
3
|
$self = $self->new if !ref $self; # inits the server when called in a static context |
2818
|
1
|
|
|
|
|
4
|
$self->init_context(); |
2819
|
|
|
|
|
|
|
# we want to restore it when we are done |
2820
|
1
|
|
|
|
|
2
|
local $SOAP::Constants::DEFAULT_XML_SCHEMA |
2821
|
|
|
|
|
|
|
= $SOAP::Constants::DEFAULT_XML_SCHEMA; |
2822
|
|
|
|
|
|
|
|
2823
|
|
|
|
|
|
|
# SOAP version WILL NOT be restored when we are done. |
2824
|
|
|
|
|
|
|
# is it problem? |
2825
|
|
|
|
|
|
|
|
2826
|
1
|
|
|
|
|
2
|
my $result = eval { |
2827
|
1
|
|
|
|
|
4
|
local $SIG{__DIE__}; |
2828
|
|
|
|
|
|
|
# why is this here: |
2829
|
1
|
|
|
|
|
3
|
$self->serializer->soapversion(1.1); |
2830
|
1
|
|
|
|
|
2
|
my $request = eval { $self->deserializer->deserialize($_[0]) }; |
|
1
|
|
|
|
|
3
|
|
2831
|
|
|
|
|
|
|
|
2832
|
1
|
50
|
33
|
|
|
18
|
die SOAP::Fault |
2833
|
|
|
|
|
|
|
->faultcode($SOAP::Constants::FAULT_VERSION_MISMATCH) |
2834
|
|
|
|
|
|
|
->faultstring($@) |
2835
|
|
|
|
|
|
|
if $@ && $@ =~ /^$SOAP::Constants::WRONG_VERSION/; |
2836
|
|
|
|
|
|
|
|
2837
|
1
|
50
|
|
|
|
8
|
die "Application failed during request deserialization: $@" if $@; |
2838
|
0
|
|
|
|
|
0
|
my $som = ref $request; |
2839
|
0
|
0
|
|
|
|
0
|
die "Can't find root element in the message" |
2840
|
|
|
|
|
|
|
unless $request->match($som->envelope); |
2841
|
0
|
|
|
|
|
0
|
$self->serializer->soapversion(SOAP::Lite->soapversion); |
2842
|
0
|
0
|
|
|
|
0
|
$self->serializer->xmlschema($SOAP::Constants::DEFAULT_XML_SCHEMA |
2843
|
|
|
|
|
|
|
= $self->deserializer->xmlschema) |
2844
|
|
|
|
|
|
|
if $self->deserializer->xmlschema; |
2845
|
|
|
|
|
|
|
|
2846
|
0
|
0
|
0
|
|
|
0
|
die SOAP::Fault |
2847
|
|
|
|
|
|
|
->faultcode($SOAP::Constants::FAULT_MUST_UNDERSTAND) |
2848
|
|
|
|
|
|
|
->faultstring("Unrecognized header has mustUnderstand attribute set to 'true'") |
2849
|
|
|
|
|
|
|
if !$SOAP::Constants::DO_NOT_CHECK_MUSTUNDERSTAND && |
2850
|
|
|
|
|
|
|
grep { |
2851
|
0
|
0
|
0
|
|
|
0
|
$_->mustUnderstand |
2852
|
|
|
|
|
|
|
&& (!$_->actor || $_->actor eq $SOAP::Constants::NEXT_ACTOR) |
2853
|
|
|
|
|
|
|
} $request->dataof($som->headers); |
2854
|
|
|
|
|
|
|
|
2855
|
0
|
0
|
|
|
|
0
|
die "Can't find method element in the message" |
2856
|
|
|
|
|
|
|
unless $request->match($som->method); |
2857
|
|
|
|
|
|
|
# TODO - SOAP::Dispatcher plugs in here |
2858
|
|
|
|
|
|
|
# my $handler = $self->dispatcher->find_handler($request); |
2859
|
0
|
|
|
|
|
0
|
my($class, $method_uri, $method_name) = $self->find_target($request); |
2860
|
0
|
|
|
|
|
0
|
my @results = eval { |
2861
|
0
|
|
|
|
|
0
|
local $^W; |
2862
|
0
|
|
|
|
|
0
|
my @parameters = $request->paramsin; |
2863
|
|
|
|
|
|
|
|
2864
|
|
|
|
|
|
|
# SOAP::Trace::dispatch($fullname); |
2865
|
0
|
|
|
|
|
0
|
SOAP::Trace::parameters(@parameters); |
2866
|
|
|
|
|
|
|
|
2867
|
0
|
0
|
|
|
|
0
|
push @parameters, $request |
2868
|
|
|
|
|
|
|
if UNIVERSAL::isa($class => 'SOAP::Server::Parameters'); |
2869
|
|
|
|
|
|
|
|
2870
|
25
|
|
|
25
|
|
839
|
no strict qw(refs); |
|
25
|
|
|
|
|
43
|
|
|
25
|
|
|
|
|
10867
|
|
2871
|
|
|
|
|
|
|
SOAP::Server::Object->references( |
2872
|
|
|
|
|
|
|
defined $parameters[0] |
2873
|
|
|
|
|
|
|
&& ref $parameters[0] |
2874
|
|
|
|
|
|
|
&& UNIVERSAL::isa($parameters[0] => $class) |
2875
|
0
|
0
|
0
|
|
|
0
|
? do { |
2876
|
0
|
|
|
|
|
0
|
my $object = shift @parameters; |
2877
|
0
|
0
|
|
|
|
0
|
SOAP::Server::Object->object(ref $class |
2878
|
|
|
|
|
|
|
? $class |
2879
|
|
|
|
|
|
|
: $object |
2880
|
|
|
|
|
|
|
)->$method_name(SOAP::Server::Object->objects(@parameters)), |
2881
|
|
|
|
|
|
|
|
2882
|
|
|
|
|
|
|
# send object back as a header |
2883
|
|
|
|
|
|
|
# preserve name, specify URI |
2884
|
|
|
|
|
|
|
SOAP::Header |
2885
|
|
|
|
|
|
|
->uri($SOAP::Constants::NS_SL_HEADER => $object) |
2886
|
|
|
|
|
|
|
->name($request->dataof($som->method.'/[1]')->name) |
2887
|
|
|
|
|
|
|
} # end do block |
2888
|
|
|
|
|
|
|
|
2889
|
|
|
|
|
|
|
# SOAP::Dispatcher will plug-in here as well |
2890
|
|
|
|
|
|
|
# $handler->dispatch(SOAP::Server::Object->objects(@parameters) |
2891
|
|
|
|
|
|
|
: $class->$method_name(SOAP::Server::Object->objects(@parameters)) ); |
2892
|
|
|
|
|
|
|
}; # end eval block |
2893
|
0
|
|
|
|
|
0
|
SOAP::Trace::result(@results); |
2894
|
|
|
|
|
|
|
|
2895
|
|
|
|
|
|
|
# let application errors pass through with 'Server' code |
2896
|
0
|
0
|
|
|
|
0
|
die ref $@ |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2897
|
|
|
|
|
|
|
? $@ |
2898
|
|
|
|
|
|
|
: $@ =~ /^Can\'t locate object method "$method_name"/ |
2899
|
|
|
|
|
|
|
? "Failed to locate method ($method_name) in class ($class)" |
2900
|
|
|
|
|
|
|
: SOAP::Fault->faultcode($SOAP::Constants::FAULT_SERVER)->faultstring($@) |
2901
|
|
|
|
|
|
|
if $@; |
2902
|
|
|
|
|
|
|
|
2903
|
0
|
|
|
|
|
0
|
my $result = $self->serializer |
2904
|
|
|
|
|
|
|
->prefix('s') # distinguish generated element names between client and server |
2905
|
|
|
|
|
|
|
->uri($method_uri) |
2906
|
|
|
|
|
|
|
->envelope(response => $method_name . 'Response', @results); |
2907
|
0
|
|
|
|
|
0
|
return $result; |
2908
|
|
|
|
|
|
|
}; |
2909
|
|
|
|
|
|
|
|
2910
|
|
|
|
|
|
|
# void context |
2911
|
1
|
50
|
|
|
|
4
|
return unless defined wantarray; |
2912
|
|
|
|
|
|
|
|
2913
|
|
|
|
|
|
|
# normal result |
2914
|
1
|
50
|
|
|
|
6
|
return $result unless $@; |
2915
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
# check fails, something wrong with message |
2917
|
1
|
50
|
|
|
|
6
|
return $self->make_fault($SOAP::Constants::FAULT_CLIENT, $@) unless ref $@; |
2918
|
|
|
|
|
|
|
|
2919
|
|
|
|
|
|
|
# died with SOAP::Fault |
2920
|
0
|
0
|
0
|
|
|
0
|
return $self->make_fault($@->faultcode || $SOAP::Constants::FAULT_SERVER, |
|
|
|
0
|
|
|
|
|
2921
|
|
|
|
|
|
|
$@->faultstring || 'Application error', |
2922
|
|
|
|
|
|
|
$@->faultdetail, $@->faultactor) |
2923
|
|
|
|
|
|
|
if UNIVERSAL::isa($@ => 'SOAP::Fault'); |
2924
|
|
|
|
|
|
|
|
2925
|
|
|
|
|
|
|
# died with complex detail |
2926
|
0
|
|
|
|
|
0
|
return $self->make_fault($SOAP::Constants::FAULT_SERVER, 'Application error' => $@); |
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
} # end of handle() |
2929
|
|
|
|
|
|
|
|
2930
|
|
|
|
|
|
|
sub make_fault { |
2931
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
2932
|
1
|
|
|
|
|
3
|
my($code, $string, $detail, $actor) = @_; |
2933
|
1
|
|
33
|
|
|
2
|
$self->serializer->fault($code, $string, $detail, $actor || $self->myuri); |
2934
|
|
|
|
|
|
|
} |
2935
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
# ====================================================================== |
2937
|
|
|
|
|
|
|
|
2938
|
|
|
|
|
|
|
package SOAP::Trace; |
2939
|
|
|
|
|
|
|
|
2940
|
25
|
|
|
25
|
|
151
|
use Carp (); |
|
25
|
|
|
|
|
39
|
|
|
25
|
|
|
|
|
849
|
|
2941
|
|
|
|
|
|
|
|
2942
|
|
|
|
|
|
|
my @list = qw( |
2943
|
|
|
|
|
|
|
transport dispatch result |
2944
|
|
|
|
|
|
|
parameters headers objects |
2945
|
|
|
|
|
|
|
method fault freeform |
2946
|
|
|
|
|
|
|
trace debug); |
2947
|
|
|
|
|
|
|
{ |
2948
|
25
|
|
|
25
|
|
103
|
no strict 'refs'; |
|
25
|
|
|
|
|
35
|
|
|
25
|
|
|
|
|
3632
|
|
2949
|
|
|
|
|
|
|
for (@list) { |
2950
|
551
|
|
|
551
|
|
4101
|
*$_ = sub {} |
2951
|
|
|
|
|
|
|
} |
2952
|
|
|
|
|
|
|
} |
2953
|
|
|
|
|
|
|
|
2954
|
|
|
|
|
|
|
sub defaultlog { |
2955
|
0
|
|
|
0
|
|
0
|
my $caller = (caller(1))[3]; # the 4th element returned by caller is the subroutine name |
2956
|
0
|
0
|
|
|
|
0
|
$caller = (caller(2))[3] if $caller =~ /eval/; |
2957
|
0
|
|
|
|
|
0
|
chomp(my $msg = join ' ', @_); |
2958
|
0
|
|
|
|
|
0
|
printf STDERR "%s: %s\n", $caller, $msg; |
2959
|
|
|
|
|
|
|
} |
2960
|
|
|
|
|
|
|
|
2961
|
|
|
|
|
|
|
sub import { |
2962
|
25
|
|
|
25
|
|
132
|
no strict 'refs'; |
|
25
|
|
|
|
|
39
|
|
|
25
|
|
|
|
|
766
|
|
2963
|
25
|
|
|
25
|
|
102
|
no warnings qw{ redefine }; # suppress warnings about redefining |
|
25
|
|
|
|
|
30
|
|
|
25
|
|
|
|
|
6700
|
|
2964
|
0
|
|
|
0
|
|
0
|
my $pack = shift; |
2965
|
0
|
|
|
|
|
0
|
my(@notrace, @symbols); |
2966
|
0
|
|
|
|
|
0
|
for (@_) { |
2967
|
0
|
0
|
|
|
|
0
|
if (ref eq 'CODE') { |
2968
|
0
|
|
|
|
|
0
|
my $call = $_; |
2969
|
0
|
|
|
0
|
|
0
|
foreach (@symbols) { *$_ = sub { $call->(@_) } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2970
|
0
|
|
|
|
|
0
|
@symbols = (); |
2971
|
|
|
|
|
|
|
} |
2972
|
|
|
|
|
|
|
else { |
2973
|
0
|
|
|
|
|
0
|
local $_ = $_; |
2974
|
0
|
|
|
|
|
0
|
my $minus = s/^-//; |
2975
|
0
|
|
|
|
|
0
|
my $all = $_ eq 'all'; |
2976
|
0
|
0
|
0
|
|
|
0
|
Carp::carp "Illegal symbol for tracing ($_)" unless $all || $pack->can($_); |
2977
|
0
|
0
|
|
|
|
0
|
$minus ? push(@notrace, $all ? @list : $_) : push(@symbols, $all ? @list : $_); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2978
|
|
|
|
|
|
|
} |
2979
|
|
|
|
|
|
|
} |
2980
|
0
|
|
|
|
|
0
|
foreach (@symbols) { *$_ = \&defaultlog } |
|
0
|
|
|
|
|
0
|
|
2981
|
0
|
|
|
0
|
|
0
|
foreach (@notrace) { *$_ = sub {} } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
2982
|
|
|
|
|
|
|
} |
2983
|
|
|
|
|
|
|
|
2984
|
|
|
|
|
|
|
# ====================================================================== |
2985
|
|
|
|
|
|
|
|
2986
|
|
|
|
|
|
|
package SOAP::Custom::XML::Data; |
2987
|
|
|
|
|
|
|
|
2988
|
25
|
|
|
25
|
|
129
|
use vars qw(@ISA $AUTOLOAD); |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
2161
|
|
2989
|
|
|
|
|
|
|
@ISA = qw(SOAP::Data); |
2990
|
|
|
|
|
|
|
|
2991
|
25
|
|
|
25
|
|
139
|
use overload fallback => 1, '""' => sub { shift->value }; |
|
25
|
|
|
0
|
|
37
|
|
|
25
|
|
|
|
|
297
|
|
|
0
|
|
|
|
|
0
|
|
2992
|
|
|
|
|
|
|
|
2993
|
|
|
|
|
|
|
sub _compileit { |
2994
|
25
|
|
|
25
|
|
2209
|
no strict 'refs'; |
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
4230
|
|
2995
|
100
|
|
|
100
|
|
147
|
my $method = shift; |
2996
|
|
|
|
|
|
|
*$method = sub { |
2997
|
1
|
50
|
|
1
|
|
10
|
return __PACKAGE__->SUPER::name($method => $_[0]->attr->{$method}) |
2998
|
|
|
|
|
|
|
if exists $_[0]->attr->{$method}; |
2999
|
0
|
0
|
0
|
|
|
0
|
my @elems = grep { |
3000
|
1
|
|
|
|
|
7
|
ref $_ && UNIVERSAL::isa($_ => __PACKAGE__) |
3001
|
|
|
|
|
|
|
&& $_->SUPER::name =~ /(^|:)$method$/ |
3002
|
|
|
|
|
|
|
} $_[0]->value; |
3003
|
1
|
50
|
|
|
|
4
|
return wantarray? @elems : $elems[0]; |
3004
|
100
|
|
|
|
|
2922
|
}; |
3005
|
|
|
|
|
|
|
} |
3006
|
|
|
|
|
|
|
|
3007
|
25
|
|
|
25
|
|
69
|
sub BEGIN { foreach (qw(name type import use)) { _compileit($_) } } |
|
100
|
|
|
|
|
167
|
|
3008
|
|
|
|
|
|
|
|
3009
|
|
|
|
|
|
|
sub AUTOLOAD { |
3010
|
0
|
|
|
0
|
|
0
|
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); |
3011
|
0
|
0
|
|
|
|
0
|
return if $method eq 'DESTROY'; |
3012
|
|
|
|
|
|
|
|
3013
|
0
|
|
|
|
|
0
|
_compileit($method); |
3014
|
0
|
|
|
|
|
0
|
goto &$AUTOLOAD; |
3015
|
|
|
|
|
|
|
} |
3016
|
|
|
|
|
|
|
|
3017
|
|
|
|
|
|
|
# ====================================================================== |
3018
|
|
|
|
|
|
|
|
3019
|
|
|
|
|
|
|
package SOAP::Custom::XML::Deserializer; |
3020
|
|
|
|
|
|
|
|
3021
|
25
|
|
|
25
|
|
165
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
33
|
|
|
25
|
|
|
|
|
4264
|
|
3022
|
|
|
|
|
|
|
@ISA = qw(SOAP::Deserializer); |
3023
|
|
|
|
|
|
|
|
3024
|
|
|
|
|
|
|
sub decode_value { |
3025
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3026
|
0
|
|
|
|
|
0
|
my $ref = shift; |
3027
|
0
|
|
|
|
|
0
|
my($name, $attrs, $children, $value) = @$ref; |
3028
|
|
|
|
|
|
|
# base class knows what to do with it |
3029
|
0
|
0
|
|
|
|
0
|
return $self->SUPER::decode_value($ref) if exists $attrs->{href}; |
3030
|
|
|
|
|
|
|
|
3031
|
0
|
0
|
0
|
|
|
0
|
SOAP::Custom::XML::Data |
3032
|
|
|
|
|
|
|
-> SOAP::Data::name($name) |
3033
|
|
|
|
|
|
|
-> attr($attrs) |
3034
|
|
|
|
|
|
|
-> set_value(ref $children && @$children |
3035
|
|
|
|
|
|
|
? map(scalar(($self->decode_object($_))[1]), @$children) |
3036
|
|
|
|
|
|
|
: $value); |
3037
|
|
|
|
|
|
|
} |
3038
|
|
|
|
|
|
|
|
3039
|
|
|
|
|
|
|
# ====================================================================== |
3040
|
|
|
|
|
|
|
|
3041
|
|
|
|
|
|
|
package SOAP::Schema::Deserializer; |
3042
|
|
|
|
|
|
|
|
3043
|
25
|
|
|
25
|
|
131
|
use vars qw(@ISA); |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
1534
|
|
3044
|
|
|
|
|
|
|
@ISA = qw(SOAP::Custom::XML::Deserializer); |
3045
|
|
|
|
|
|
|
|
3046
|
|
|
|
|
|
|
# ====================================================================== |
3047
|
|
|
|
|
|
|
|
3048
|
|
|
|
|
|
|
package SOAP::Schema::WSDL; |
3049
|
|
|
|
|
|
|
|
3050
|
25
|
|
|
25
|
|
110
|
use vars qw(%imported @ISA); |
|
25
|
|
|
|
|
30
|
|
|
25
|
|
|
|
|
31523
|
|
3051
|
|
|
|
|
|
|
@ISA = qw(SOAP::Schema); |
3052
|
|
|
|
|
|
|
|
3053
|
|
|
|
|
|
|
sub new { |
3054
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3055
|
|
|
|
|
|
|
|
3056
|
0
|
0
|
|
|
|
0
|
unless (ref $self) { |
3057
|
0
|
|
|
|
|
0
|
my $class = $self; |
3058
|
0
|
|
|
|
|
0
|
$self = $class->SUPER::new(@_); |
3059
|
|
|
|
|
|
|
} |
3060
|
0
|
|
|
|
|
0
|
return $self; |
3061
|
|
|
|
|
|
|
} |
3062
|
|
|
|
|
|
|
|
3063
|
|
|
|
|
|
|
sub base { |
3064
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3065
|
|
|
|
|
|
|
@_ |
3066
|
0
|
0
|
|
|
|
0
|
? ($self->{_base} = shift, return $self) |
3067
|
|
|
|
|
|
|
: return $self->{_base}; |
3068
|
|
|
|
|
|
|
} |
3069
|
|
|
|
|
|
|
|
3070
|
|
|
|
|
|
|
sub import { |
3071
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3072
|
0
|
|
|
|
|
0
|
my $s = shift; |
3073
|
0
|
|
0
|
|
|
0
|
my $base = shift || $self->base || die "Missing base argument for ", __PACKAGE__, "\n"; |
3074
|
|
|
|
|
|
|
|
3075
|
0
|
|
|
|
|
0
|
my @a = $s->import; |
3076
|
0
|
|
|
|
|
0
|
local %imported = %imported; |
3077
|
0
|
|
|
|
|
0
|
foreach (@a) { |
3078
|
0
|
0
|
|
|
|
0
|
next unless $_->location; |
3079
|
0
|
|
|
|
|
0
|
my $location = URI->new_abs($_->location->value, $base)->as_string; |
3080
|
0
|
0
|
|
|
|
0
|
if ($imported{$location}++) { |
3081
|
0
|
0
|
|
|
|
0
|
warn "Recursion loop detected in service description from '$location'. Ignored\n" if $^W; |
3082
|
0
|
|
|
|
|
0
|
return $s; |
3083
|
|
|
|
|
|
|
} |
3084
|
0
|
|
|
|
|
0
|
my $root = $self->import( |
3085
|
|
|
|
|
|
|
$self->deserializer->deserialize( |
3086
|
|
|
|
|
|
|
$self->access($location) |
3087
|
|
|
|
|
|
|
)->root, $location); |
3088
|
|
|
|
|
|
|
|
3089
|
|
|
|
|
|
|
$root->SOAP::Data::name eq 'definitions' ? $s->set_value($s->value, $root->value) : |
3090
|
0
|
0
|
|
|
|
0
|
$root->SOAP::Data::name eq 'schema' ? do { # add element if there is no one |
|
|
0
|
|
|
|
|
|
3091
|
0
|
0
|
|
|
|
0
|
$s->set_value($s->value, $self->deserializer->deserialize('')->root) unless $s->types; |
3092
|
0
|
|
|
|
|
0
|
$s->types->set_value($s->types->value, $root) } : |
3093
|
0
|
|
|
|
|
0
|
die "Don't know what to do with '@{[$root->SOAP::Data::name]}' in schema imported from '$location'\n"; |
3094
|
|
|
|
|
|
|
} |
3095
|
|
|
|
|
|
|
|
3096
|
|
|
|
|
|
|
# return the parsed WSDL file |
3097
|
0
|
|
|
|
|
0
|
$s; |
3098
|
|
|
|
|
|
|
} |
3099
|
|
|
|
|
|
|
|
3100
|
|
|
|
|
|
|
# TODO - This is woefully incomplete! |
3101
|
|
|
|
|
|
|
sub parse_schema_element { |
3102
|
0
|
|
|
0
|
|
0
|
my $element = shift; |
3103
|
|
|
|
|
|
|
# Current element is a complex type |
3104
|
0
|
0
|
|
|
|
0
|
if (defined($element->complexType)) { |
|
|
0
|
|
|
|
|
|
3105
|
0
|
|
|
|
|
0
|
my @elements = (); |
3106
|
0
|
0
|
|
|
|
0
|
if (defined($element->complexType->sequence)) { |
3107
|
|
|
|
|
|
|
|
3108
|
0
|
|
|
|
|
0
|
foreach my $e ($element->complexType->sequence->element) { |
3109
|
0
|
|
|
|
|
0
|
push @elements,parse_schema_element($e); |
3110
|
|
|
|
|
|
|
} |
3111
|
|
|
|
|
|
|
} |
3112
|
0
|
|
|
|
|
0
|
return @elements; |
3113
|
|
|
|
|
|
|
} |
3114
|
|
|
|
|
|
|
elsif ($element->simpleType) { |
3115
|
|
|
|
|
|
|
} |
3116
|
|
|
|
|
|
|
else { |
3117
|
0
|
|
|
|
|
0
|
return $element; |
3118
|
|
|
|
|
|
|
} |
3119
|
|
|
|
|
|
|
} |
3120
|
|
|
|
|
|
|
|
3121
|
|
|
|
|
|
|
sub parse { |
3122
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3123
|
0
|
|
|
|
|
0
|
my($s, $service, $port) = @_; |
3124
|
0
|
|
|
|
|
0
|
my @result; |
3125
|
|
|
|
|
|
|
|
3126
|
|
|
|
|
|
|
# handle imports |
3127
|
0
|
|
|
|
|
0
|
$self->import($s); |
3128
|
|
|
|
|
|
|
|
3129
|
|
|
|
|
|
|
# handle descriptions without , aka tModel-type descriptions |
3130
|
0
|
|
|
|
|
0
|
my @services = $s->service; |
3131
|
0
|
|
|
|
|
0
|
my $tns = $s->{'_attr'}->{'targetNamespace'}; |
3132
|
|
|
|
|
|
|
# if there is no element we'll provide it |
3133
|
0
|
0
|
|
|
|
0
|
@services = $self->deserializer->deserialize(<<"FAKE")->root->service unless @services; |
3134
|
|
|
|
|
|
|
|
3135
|
0
|
|
0
|
|
|
0
|
|
|
0
|
|
0
|
|
|
0
|
|
3136
|
0
|
|
|
|
|
0
|
|
3137
|
|
|
|
|
|
|
|
3138
|
|
|
|
|
|
|
|
3139
|
|
|
|
|
|
|
FAKE |
3140
|
|
|
|
|
|
|
|
3141
|
0
|
|
|
|
|
0
|
my $has_warned = 0; |
3142
|
0
|
|
|
|
|
0
|
foreach (@services) { |
3143
|
0
|
|
|
|
|
0
|
my $name = $_->name; |
3144
|
0
|
0
|
0
|
|
|
0
|
next if $service && $service ne $name; |
3145
|
0
|
|
|
|
|
0
|
my %services; |
3146
|
0
|
|
|
|
|
0
|
foreach ($_->port) { |
3147
|
0
|
0
|
0
|
|
|
0
|
next if $port && $port ne $_->name; |
3148
|
0
|
|
|
|
|
0
|
my $binding = SOAP::Utils::disqualify($_->binding); |
3149
|
0
|
0
|
|
|
|
0
|
my $endpoint = ref $_->address ? $_->address->location : undef; |
3150
|
0
|
|
|
|
|
0
|
foreach ($s->binding) { |
3151
|
|
|
|
|
|
|
# is this a SOAP binding? |
3152
|
0
|
0
|
|
|
|
0
|
next unless grep { $_->uri eq 'http://schemas.xmlsoap.org/wsdl/soap/' } $_->binding; |
|
0
|
|
|
|
|
0
|
|
3153
|
0
|
0
|
|
|
|
0
|
next unless $_->name eq $binding; |
3154
|
0
|
|
|
|
|
0
|
my $default_style = $_->binding->style; |
3155
|
0
|
|
|
|
|
0
|
my $porttype = SOAP::Utils::disqualify($_->type); |
3156
|
0
|
|
|
|
|
0
|
foreach ($_->operation) { |
3157
|
0
|
|
|
|
|
0
|
my $opername = $_->name; |
3158
|
0
|
|
|
|
|
0
|
$services{$opername} = {}; # should be initialized in 5.7 and after |
3159
|
0
|
|
|
|
|
0
|
my $soapaction = $_->operation->soapAction; |
3160
|
0
|
|
0
|
|
|
0
|
my $invocationStyle = $_->operation->style || $default_style || "rpc"; |
3161
|
0
|
|
0
|
|
|
0
|
my $encodingStyle = $_->input->body->use || "encoded"; |
3162
|
0
|
|
0
|
|
|
0
|
my $namespace = $_->input->body->namespace || $tns; |
3163
|
0
|
|
|
|
|
0
|
my @parts; |
3164
|
0
|
|
|
|
|
0
|
foreach ($s->portType) { |
3165
|
0
|
0
|
|
|
|
0
|
next unless $_->name eq $porttype; |
3166
|
0
|
|
|
|
|
0
|
foreach ($_->operation) { |
3167
|
0
|
0
|
|
|
|
0
|
next unless $_->name eq $opername; |
3168
|
0
|
|
|
|
|
0
|
my $inputmessage = SOAP::Utils::disqualify($_->input->message); |
3169
|
0
|
|
|
|
|
0
|
foreach my $msg ($s->message) { |
3170
|
0
|
0
|
|
|
|
0
|
next unless $msg->name eq $inputmessage; |
3171
|
0
|
0
|
0
|
|
|
0
|
if ($invocationStyle eq "document" && $encodingStyle eq "literal") { |
3172
|
|
|
|
|
|
|
# warn "document/literal support is EXPERIMENTAL in SOAP::Lite" |
3173
|
|
|
|
|
|
|
# if !$has_warned && ($has_warned = 1); |
3174
|
0
|
|
|
|
|
0
|
my ($input_ns,$input_name) = SOAP::Utils::splitqname($msg->part->element); |
3175
|
0
|
|
|
|
|
0
|
foreach my $schema ($s->types->schema) { |
3176
|
0
|
|
|
|
|
0
|
foreach my $element ($schema->element) { |
3177
|
0
|
0
|
|
|
|
0
|
next unless $element->name eq $input_name; |
3178
|
0
|
|
|
|
|
0
|
push @parts,parse_schema_element($element); |
3179
|
|
|
|
|
|
|
} |
3180
|
0
|
|
|
|
|
0
|
$services{$opername}->{parameters} = [ @parts ]; |
3181
|
|
|
|
|
|
|
} |
3182
|
|
|
|
|
|
|
} |
3183
|
|
|
|
|
|
|
else { |
3184
|
|
|
|
|
|
|
# TODO - support all combinations of doc|rpc/lit|enc. |
3185
|
|
|
|
|
|
|
#warn "$invocationStyle/$encodingStyle is not supported in this version of SOAP::Lite"; |
3186
|
0
|
|
|
|
|
0
|
@parts = $msg->part; |
3187
|
0
|
|
|
|
|
0
|
$services{$opername}->{parameters} = [ @parts ]; |
3188
|
|
|
|
|
|
|
} |
3189
|
|
|
|
|
|
|
} |
3190
|
|
|
|
|
|
|
} |
3191
|
|
|
|
|
|
|
|
3192
|
0
|
|
|
|
|
0
|
for ($services{$opername}) { |
3193
|
0
|
|
|
|
|
0
|
$_->{endpoint} = $endpoint; |
3194
|
0
|
|
|
|
|
0
|
$_->{soapaction} = $soapaction; |
3195
|
0
|
|
|
|
|
0
|
$_->{namespace} = $namespace; |
3196
|
|
|
|
|
|
|
# $_->{parameters} = [@parts]; |
3197
|
|
|
|
|
|
|
} |
3198
|
|
|
|
|
|
|
} |
3199
|
|
|
|
|
|
|
} |
3200
|
|
|
|
|
|
|
} |
3201
|
|
|
|
|
|
|
} |
3202
|
|
|
|
|
|
|
# fix nonallowed characters in package name, and add 's' if started with digit |
3203
|
0
|
|
|
|
|
0
|
for ($name) { s/\W+/_/g; s/^(\d)/s$1/ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3204
|
0
|
|
|
|
|
0
|
push @result, $name => \%services; |
3205
|
|
|
|
|
|
|
} |
3206
|
0
|
|
|
|
|
0
|
return @result; |
3207
|
|
|
|
|
|
|
} |
3208
|
|
|
|
|
|
|
|
3209
|
|
|
|
|
|
|
# ====================================================================== |
3210
|
|
|
|
|
|
|
|
3211
|
|
|
|
|
|
|
# Naming? SOAP::Service::Schema? |
3212
|
|
|
|
|
|
|
package SOAP::Schema; |
3213
|
|
|
|
|
|
|
|
3214
|
25
|
|
|
25
|
|
164
|
use Carp (); |
|
25
|
|
|
|
|
37
|
|
|
25
|
|
|
|
|
3766
|
|
3215
|
|
|
|
|
|
|
|
3216
|
0
|
|
|
0
|
|
0
|
sub DESTROY { SOAP::Trace::objects('()') } |
3217
|
|
|
|
|
|
|
|
3218
|
|
|
|
|
|
|
sub new { |
3219
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3220
|
0
|
0
|
|
|
|
0
|
return $self if ref $self; |
3221
|
0
|
0
|
|
|
|
0
|
unless (ref $self) { |
3222
|
0
|
|
|
|
|
0
|
my $class = $self; |
3223
|
0
|
|
|
|
|
0
|
require LWP::UserAgent; |
3224
|
0
|
|
|
|
|
0
|
$self = bless { |
3225
|
|
|
|
|
|
|
'_deserializer' => SOAP::Schema::Deserializer->new, |
3226
|
|
|
|
|
|
|
'_useragent' => LWP::UserAgent->new, |
3227
|
|
|
|
|
|
|
}, $class; |
3228
|
|
|
|
|
|
|
|
3229
|
0
|
|
|
|
|
0
|
SOAP::Trace::objects('()'); |
3230
|
|
|
|
|
|
|
} |
3231
|
|
|
|
|
|
|
|
3232
|
0
|
0
|
0
|
|
|
0
|
Carp::carp "Odd (wrong?) number of parameters in new()" if $^W && (@_ & 1); |
3233
|
25
|
|
|
25
|
|
139
|
no strict qw(refs); |
|
25
|
|
|
|
|
43
|
|
|
25
|
|
|
|
|
2757
|
|
3234
|
0
|
|
|
|
|
0
|
while (@_) { |
3235
|
0
|
|
|
|
|
0
|
my $method = shift; |
3236
|
0
|
0
|
|
|
|
0
|
$self->$method(shift) if $self->can($method) |
3237
|
|
|
|
|
|
|
} |
3238
|
|
|
|
|
|
|
|
3239
|
0
|
|
|
|
|
0
|
return $self; |
3240
|
|
|
|
|
|
|
} |
3241
|
|
|
|
|
|
|
|
3242
|
|
|
|
|
|
|
sub schema { |
3243
|
0
|
|
|
0
|
|
0
|
warn "SOAP::Schema->schema has been deprecated. " |
3244
|
|
|
|
|
|
|
. "Please use SOAP::Schema->schema_url instead."; |
3245
|
0
|
|
|
|
|
0
|
return shift->schema_url(@_); |
3246
|
|
|
|
|
|
|
} |
3247
|
|
|
|
|
|
|
|
3248
|
|
|
|
|
|
|
sub BEGIN { |
3249
|
25
|
|
|
25
|
|
122
|
no strict 'refs'; |
|
25
|
|
|
|
|
49
|
|
|
25
|
|
|
|
|
2105
|
|
3250
|
25
|
|
|
25
|
|
61
|
for my $method (qw(deserializer schema_url services useragent stub cache_dir cache_ttl)) { |
3251
|
175
|
|
|
|
|
242
|
my $field = '_' . $method; |
3252
|
|
|
|
|
|
|
*$method = sub { |
3253
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3254
|
0
|
0
|
|
|
|
0
|
@_ ? ($self->{$field} = shift, return $self) : return $self->{$field}; |
3255
|
|
|
|
|
|
|
} |
3256
|
175
|
|
|
|
|
27933
|
} |
3257
|
|
|
|
|
|
|
} |
3258
|
|
|
|
|
|
|
|
3259
|
|
|
|
|
|
|
sub parse { |
3260
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3261
|
0
|
|
|
|
|
0
|
my $s = $self->deserializer->deserialize($self->access)->root; |
3262
|
|
|
|
|
|
|
# here should be something that defines what schema description we want to use |
3263
|
0
|
|
|
|
|
0
|
$self->services({SOAP::Schema::WSDL->base($self->schema_url)->useragent($self->useragent)->parse($s, @_)}); |
3264
|
|
|
|
|
|
|
|
3265
|
|
|
|
|
|
|
} |
3266
|
|
|
|
|
|
|
|
3267
|
|
|
|
|
|
|
sub refresh_cache { |
3268
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3269
|
0
|
|
|
|
|
0
|
my ($filename,$contents) = @_; |
3270
|
0
|
0
|
|
|
|
0
|
open CACHE,">$filename" or Carp::croak "Could not open cache file for writing: $!"; |
3271
|
0
|
|
|
|
|
0
|
print CACHE $contents; |
3272
|
0
|
|
|
|
|
0
|
close CACHE; |
3273
|
|
|
|
|
|
|
} |
3274
|
|
|
|
|
|
|
|
3275
|
|
|
|
|
|
|
sub load { |
3276
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3277
|
0
|
|
|
|
|
0
|
local $^W; # suppress warnings about redefining |
3278
|
0
|
0
|
|
|
|
0
|
foreach (keys %{$self->services || Carp::croak 'Nothing to load. Schema is not specified'}) { |
|
0
|
|
|
|
|
0
|
|
3279
|
|
|
|
|
|
|
# TODO - check age of cached file, and delete if older than configured amount |
3280
|
0
|
0
|
|
|
|
0
|
if ($self->cache_dir) { |
3281
|
0
|
|
|
|
|
0
|
my $cached_file = File::Spec->catfile($self->cache_dir,$_.".pm"); |
3282
|
0
|
|
0
|
|
|
0
|
my $ttl = $self->cache_ttl || $SOAP::Constants::DEFAULT_CACHE_TTL; |
3283
|
0
|
|
|
|
|
0
|
open (CACHE, "<$cached_file"); |
3284
|
0
|
0
|
|
|
|
0
|
my @stat = stat($cached_file) unless eof(CACHE); |
3285
|
0
|
|
|
|
|
0
|
close CACHE; |
3286
|
0
|
0
|
|
|
|
0
|
if (@stat) { |
3287
|
|
|
|
|
|
|
# Cache exists |
3288
|
0
|
|
|
|
|
0
|
my $cache_lived = time() - $stat[9]; |
3289
|
0
|
0
|
0
|
|
|
0
|
if ($ttl > 0 && $cache_lived > $ttl) { |
3290
|
0
|
|
|
|
|
0
|
$self->refresh_cache($cached_file,$self->generate_stub($_)); |
3291
|
|
|
|
|
|
|
} |
3292
|
|
|
|
|
|
|
} |
3293
|
|
|
|
|
|
|
else { |
3294
|
|
|
|
|
|
|
# Cache doesn't exist |
3295
|
0
|
|
|
|
|
0
|
$self->refresh_cache($cached_file,$self->generate_stub($_)); |
3296
|
|
|
|
|
|
|
} |
3297
|
0
|
|
|
|
|
0
|
push @INC,$self->cache_dir; |
3298
|
0
|
0
|
|
|
|
0
|
eval "require $_" or Carp::croak "Could not load cached file: $@"; |
3299
|
|
|
|
|
|
|
} |
3300
|
|
|
|
|
|
|
else { |
3301
|
0
|
0
|
|
|
|
0
|
eval $self->generate_stub($_) or Carp::croak "Bad stub: $@"; |
3302
|
|
|
|
|
|
|
} |
3303
|
|
|
|
|
|
|
} |
3304
|
0
|
|
|
|
|
0
|
$self; |
3305
|
|
|
|
|
|
|
} |
3306
|
|
|
|
|
|
|
|
3307
|
|
|
|
|
|
|
sub access { |
3308
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3309
|
0
|
|
0
|
|
|
0
|
my $url = shift || $self->schema_url || Carp::croak 'Nothing to access. URL is not specified'; |
3310
|
0
|
0
|
|
|
|
0
|
$self->useragent->env_proxy if $ENV{'HTTP_proxy'}; |
3311
|
|
|
|
|
|
|
|
3312
|
0
|
|
|
|
|
0
|
my $req = HTTP::Request->new(GET => $url); |
3313
|
0
|
0
|
0
|
|
|
0
|
$req->proxy_authorization_basic($ENV{'HTTP_proxy_user'}, $ENV{'HTTP_proxy_pass'}) |
3314
|
|
|
|
|
|
|
if ($ENV{'HTTP_proxy_user'} && $ENV{'HTTP_proxy_pass'}); |
3315
|
|
|
|
|
|
|
|
3316
|
0
|
|
|
|
|
0
|
my $resp = $self->useragent->request($req); |
3317
|
0
|
0
|
|
|
|
0
|
$resp->is_success ? $resp->content : die "Service description '$url' can't be loaded: ", $resp->status_line, "\n"; |
3318
|
|
|
|
|
|
|
} |
3319
|
|
|
|
|
|
|
|
3320
|
|
|
|
|
|
|
sub generate_stub { |
3321
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3322
|
0
|
|
|
|
|
0
|
my $package = shift; |
3323
|
0
|
|
|
|
|
0
|
my $services = $self->services->{$package}; |
3324
|
0
|
|
|
|
|
0
|
my $schema_url = $self->schema_url; |
3325
|
|
|
|
|
|
|
|
3326
|
0
|
|
|
|
|
0
|
$self->{'_stub'} = <<"EOP"; |
3327
|
0
|
|
|
|
|
0
|
package $package; |
3328
|
|
|
|
|
|
|
# Generated by SOAP::Lite (v$SOAP::Lite::VERSION) for Perl -- soaplite.com |
3329
|
|
|
|
|
|
|
# Copyright (C) 2000-2006 Paul Kulchenko, Byrne Reese |
3330
|
|
|
|
|
|
|
# -- generated at [@{[scalar localtime]}] |
3331
|
|
|
|
|
|
|
EOP |
3332
|
0
|
0
|
|
|
|
0
|
$self->{'_stub'} .= "# -- generated from $schema_url\n" if $schema_url; |
3333
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= 'my %methods = ('."\n"; |
3334
|
0
|
|
|
|
|
0
|
foreach my $service (keys %$services) { |
3335
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= "'$service' => {\n"; |
3336
|
0
|
|
|
|
|
0
|
foreach (qw(endpoint soapaction namespace)) { |
3337
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= " $_ => '".$services->{$service}{$_}."',\n"; |
3338
|
|
|
|
|
|
|
} |
3339
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= " parameters => [\n"; |
3340
|
0
|
|
|
|
|
0
|
foreach (@{$services->{$service}{parameters}}) { |
|
0
|
|
|
|
|
0
|
|
3341
|
|
|
|
|
|
|
# This is a workaround for https://sourceforge.net/tracker/index.php?func=detail&aid=2001592&group_id=66000&atid=513017 |
3342
|
0
|
0
|
|
|
|
0
|
next unless ref $_; |
3343
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= " SOAP::Data->new(name => '".$_->name."', type => '".$_->type."', attr => {"; |
3344
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= do { |
3345
|
0
|
|
|
|
|
0
|
my %attr = %{$_->attr}; |
|
0
|
|
|
|
|
0
|
|
3346
|
0
|
|
|
|
|
0
|
join(', ', map {"'$_' => '$attr{$_}'"} |
|
0
|
|
|
|
|
0
|
|
3347
|
0
|
|
|
|
|
0
|
grep {/^xmlns:(?!-)/} |
3348
|
|
|
|
|
|
|
keys %attr); |
3349
|
|
|
|
|
|
|
}; |
3350
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= "}),\n"; |
3351
|
|
|
|
|
|
|
} |
3352
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= " ], # end parameters\n"; |
3353
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= " }, # end $service\n"; |
3354
|
|
|
|
|
|
|
} |
3355
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= "); # end my %methods\n"; |
3356
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= <<'EOP'; |
3357
|
|
|
|
|
|
|
|
3358
|
|
|
|
|
|
|
use SOAP::Lite; |
3359
|
|
|
|
|
|
|
use Exporter; |
3360
|
|
|
|
|
|
|
use Carp (); |
3361
|
|
|
|
|
|
|
|
3362
|
|
|
|
|
|
|
use vars qw(@ISA $AUTOLOAD @EXPORT_OK %EXPORT_TAGS); |
3363
|
|
|
|
|
|
|
@ISA = qw(Exporter SOAP::Lite); |
3364
|
|
|
|
|
|
|
@EXPORT_OK = (keys %methods); |
3365
|
|
|
|
|
|
|
%EXPORT_TAGS = ('all' => [@EXPORT_OK]); |
3366
|
|
|
|
|
|
|
|
3367
|
|
|
|
|
|
|
sub _call { |
3368
|
|
|
|
|
|
|
my ($self, $method) = (shift, shift); |
3369
|
|
|
|
|
|
|
my $name = UNIVERSAL::isa($method => 'SOAP::Data') ? $method->name : $method; |
3370
|
|
|
|
|
|
|
my %method = %{$methods{$name}}; |
3371
|
|
|
|
|
|
|
$self->proxy($method{endpoint} || Carp::croak "No server address (proxy) specified") |
3372
|
|
|
|
|
|
|
unless $self->proxy; |
3373
|
|
|
|
|
|
|
my @templates = @{$method{parameters}}; |
3374
|
|
|
|
|
|
|
my @parameters = (); |
3375
|
|
|
|
|
|
|
foreach my $param (@_) { |
3376
|
|
|
|
|
|
|
if (@templates) { |
3377
|
|
|
|
|
|
|
my $template = shift @templates; |
3378
|
|
|
|
|
|
|
my ($prefix,$typename) = SOAP::Utils::splitqname($template->type); |
3379
|
|
|
|
|
|
|
my $method = 'as_'.$typename; |
3380
|
|
|
|
|
|
|
# TODO - if can('as_'.$typename) {...} |
3381
|
|
|
|
|
|
|
my $result = $self->serializer->$method($param, $template->name, $template->type, $template->attr); |
3382
|
|
|
|
|
|
|
push(@parameters, $template->value($result->[2])); |
3383
|
|
|
|
|
|
|
} |
3384
|
|
|
|
|
|
|
else { |
3385
|
|
|
|
|
|
|
push(@parameters, $param); |
3386
|
|
|
|
|
|
|
} |
3387
|
|
|
|
|
|
|
} |
3388
|
|
|
|
|
|
|
$self->endpoint($method{endpoint}) |
3389
|
|
|
|
|
|
|
->ns($method{namespace}) |
3390
|
|
|
|
|
|
|
->on_action(sub{qq!"$method{soapaction}"!}); |
3391
|
|
|
|
|
|
|
EOP |
3392
|
0
|
|
|
|
|
0
|
my $namespaces = $self->deserializer->ids->[1]; |
3393
|
0
|
|
|
|
|
0
|
foreach my $key (keys %{$namespaces}) { |
|
0
|
|
|
|
|
0
|
|
3394
|
0
|
|
|
|
|
0
|
my ($ns,$prefix) = SOAP::Utils::splitqname($key); |
3395
|
0
|
0
|
0
|
|
|
0
|
$self->{'_stub'} .= ' $self->serializer->register_ns("'.$namespaces->{$key}.'","'.$prefix.'");'."\n" |
3396
|
|
|
|
|
|
|
if (defined $ns && ($ns eq "xmlns")); |
3397
|
|
|
|
|
|
|
} |
3398
|
0
|
|
|
|
|
0
|
$self->{'_stub'} .= <<'EOP'; |
3399
|
|
|
|
|
|
|
my $som = $self->SUPER::call($method => @parameters); |
3400
|
|
|
|
|
|
|
if ($self->want_som) { |
3401
|
|
|
|
|
|
|
return $som; |
3402
|
|
|
|
|
|
|
} |
3403
|
|
|
|
|
|
|
UNIVERSAL::isa($som => 'SOAP::SOM') ? wantarray ? $som->paramsall : $som->result : $som; |
3404
|
|
|
|
|
|
|
} |
3405
|
|
|
|
|
|
|
|
3406
|
|
|
|
|
|
|
sub BEGIN { |
3407
|
|
|
|
|
|
|
no strict 'refs'; |
3408
|
|
|
|
|
|
|
for my $method (qw(want_som)) { |
3409
|
|
|
|
|
|
|
my $field = '_' . $method; |
3410
|
|
|
|
|
|
|
*$method = sub { |
3411
|
|
|
|
|
|
|
my $self = shift->new; |
3412
|
|
|
|
|
|
|
@_ ? ($self->{$field} = shift, return $self) : return $self->{$field}; |
3413
|
|
|
|
|
|
|
} |
3414
|
|
|
|
|
|
|
} |
3415
|
|
|
|
|
|
|
} |
3416
|
|
|
|
|
|
|
no strict 'refs'; |
3417
|
|
|
|
|
|
|
for my $method (@EXPORT_OK) { |
3418
|
|
|
|
|
|
|
my %method = %{$methods{$method}}; |
3419
|
|
|
|
|
|
|
*$method = sub { |
3420
|
|
|
|
|
|
|
my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) |
3421
|
|
|
|
|
|
|
? ref $_[0] |
3422
|
|
|
|
|
|
|
? shift # OBJECT |
3423
|
|
|
|
|
|
|
# CLASS, either get self or create new and assign to self |
3424
|
|
|
|
|
|
|
: (shift->self || __PACKAGE__->self(__PACKAGE__->new)) |
3425
|
|
|
|
|
|
|
# function call, either get self or create new and assign to self |
3426
|
|
|
|
|
|
|
: (__PACKAGE__->self || __PACKAGE__->self(__PACKAGE__->new)); |
3427
|
|
|
|
|
|
|
$self->_call($method, @_); |
3428
|
|
|
|
|
|
|
} |
3429
|
|
|
|
|
|
|
} |
3430
|
|
|
|
|
|
|
|
3431
|
|
|
|
|
|
|
sub AUTOLOAD { |
3432
|
|
|
|
|
|
|
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); |
3433
|
|
|
|
|
|
|
return if $method eq 'DESTROY' || $method eq 'want_som'; |
3434
|
|
|
|
|
|
|
die "Unrecognized method '$method'. List of available method(s): @EXPORT_OK\n"; |
3435
|
|
|
|
|
|
|
} |
3436
|
|
|
|
|
|
|
|
3437
|
|
|
|
|
|
|
1; |
3438
|
|
|
|
|
|
|
EOP |
3439
|
0
|
|
|
|
|
0
|
return $self->stub; |
3440
|
|
|
|
|
|
|
} |
3441
|
|
|
|
|
|
|
|
3442
|
|
|
|
|
|
|
# ====================================================================== |
3443
|
|
|
|
|
|
|
|
3444
|
|
|
|
|
|
|
package SOAP; |
3445
|
|
|
|
|
|
|
|
3446
|
25
|
|
|
25
|
|
149
|
use vars qw($AUTOLOAD); |
|
25
|
|
|
|
|
46
|
|
|
25
|
|
|
|
|
1628
|
|
3447
|
|
|
|
|
|
|
require URI; |
3448
|
|
|
|
|
|
|
|
3449
|
|
|
|
|
|
|
my $soap; # shared between SOAP and SOAP::Lite packages |
3450
|
|
|
|
|
|
|
|
3451
|
|
|
|
|
|
|
{ |
3452
|
25
|
|
|
25
|
|
124
|
no strict 'refs'; |
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
11845
|
|
3453
|
|
|
|
|
|
|
*AUTOLOAD = sub { |
3454
|
0
|
|
|
0
|
|
0
|
local($1,$2); |
3455
|
0
|
|
|
|
|
0
|
my($package, $method) = $AUTOLOAD =~ m/(?:(.+)::)([^:]+)$/; |
3456
|
0
|
0
|
|
|
|
0
|
return if $method eq 'DESTROY'; |
3457
|
|
|
|
|
|
|
|
3458
|
0
|
0
|
0
|
|
|
0
|
my $soap = ref $_[0] && UNIVERSAL::isa($_[0] => 'SOAP::Lite') |
|
|
|
0
|
|
|
|
|
3459
|
|
|
|
|
|
|
? $_[0] |
3460
|
|
|
|
|
|
|
: $soap |
3461
|
|
|
|
|
|
|
|| die "SOAP:: prefix shall only be used in combination with +autodispatch option\n"; |
3462
|
|
|
|
|
|
|
|
3463
|
0
|
|
|
|
|
0
|
my $uri = URI->new($soap->uri); |
3464
|
0
|
|
|
|
|
0
|
my $currenturi = $uri->path; |
3465
|
0
|
0
|
0
|
|
|
0
|
$package = ref $_[0] && UNIVERSAL::isa($_[0] => 'SOAP::Lite') |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
3466
|
|
|
|
|
|
|
? $currenturi |
3467
|
|
|
|
|
|
|
: $package eq 'SOAP' |
3468
|
|
|
|
|
|
|
? ref $_[0] || ($_[0] eq 'SOAP' |
3469
|
|
|
|
|
|
|
? $currenturi || Carp::croak "URI is not specified for method call" |
3470
|
|
|
|
|
|
|
: $_[0]) |
3471
|
|
|
|
|
|
|
: $package eq 'main' |
3472
|
|
|
|
|
|
|
? $currenturi || $package |
3473
|
|
|
|
|
|
|
: $package; |
3474
|
|
|
|
|
|
|
|
3475
|
|
|
|
|
|
|
# drop first parameter if it's a class name |
3476
|
|
|
|
|
|
|
{ |
3477
|
0
|
|
|
|
|
0
|
my $pack = $package; |
|
0
|
|
|
|
|
0
|
|
3478
|
0
|
|
|
|
|
0
|
for ($pack) { s!^/!!; s!/!::!g; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3479
|
0
|
0
|
0
|
|
|
0
|
shift @_ if @_ && !ref $_[0] && ($_[0] eq $pack || $_[0] eq 'SOAP') |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3480
|
|
|
|
|
|
|
|| ref $_[0] && UNIVERSAL::isa($_[0] => 'SOAP::Lite'); |
3481
|
|
|
|
|
|
|
} |
3482
|
|
|
|
|
|
|
|
3483
|
0
|
|
|
|
|
0
|
for ($package) { s!::!/!g; s!^/?!/!; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3484
|
0
|
|
|
|
|
0
|
$uri->path($package); |
3485
|
|
|
|
|
|
|
|
3486
|
0
|
|
|
|
|
0
|
my $som = $soap->uri($uri->as_string)->call($method => @_); |
3487
|
0
|
0
|
|
|
|
0
|
UNIVERSAL::isa($som => 'SOAP::SOM') |
|
|
0
|
|
|
|
|
|
3488
|
|
|
|
|
|
|
? wantarray |
3489
|
|
|
|
|
|
|
? $som->paramsall |
3490
|
|
|
|
|
|
|
: $som->result |
3491
|
|
|
|
|
|
|
: $som; |
3492
|
|
|
|
|
|
|
}; |
3493
|
|
|
|
|
|
|
} |
3494
|
|
|
|
|
|
|
|
3495
|
|
|
|
|
|
|
# ====================================================================== |
3496
|
|
|
|
|
|
|
|
3497
|
|
|
|
|
|
|
package SOAP::Lite; |
3498
|
|
|
|
|
|
|
|
3499
|
25
|
|
|
25
|
|
139
|
use vars qw($AUTOLOAD @ISA); |
|
25
|
|
|
|
|
38
|
|
|
25
|
|
|
|
|
1174
|
|
3500
|
25
|
|
|
25
|
|
142
|
use Carp (); |
|
25
|
|
|
|
|
36
|
|
|
25
|
|
|
|
|
531
|
|
3501
|
|
|
|
|
|
|
|
3502
|
25
|
|
|
25
|
|
142
|
use SOAP::Lite::Utils; |
|
25
|
|
|
|
|
44
|
|
|
25
|
|
|
|
|
188
|
|
3503
|
25
|
|
|
25
|
|
15241
|
use SOAP::Constants; |
|
25
|
|
|
|
|
73
|
|
|
25
|
|
|
|
|
1203
|
|
3504
|
25
|
|
|
25
|
|
11476
|
use SOAP::Packager; |
|
25
|
|
|
|
|
71
|
|
|
25
|
|
|
|
|
875
|
|
3505
|
|
|
|
|
|
|
|
3506
|
25
|
|
|
25
|
|
149
|
use Scalar::Util qw(weaken blessed); |
|
25
|
|
|
|
|
98
|
|
|
25
|
|
|
|
|
11070
|
|
3507
|
|
|
|
|
|
|
|
3508
|
|
|
|
|
|
|
@ISA = qw(SOAP::Cloneable); |
3509
|
|
|
|
|
|
|
|
3510
|
|
|
|
|
|
|
# provide access to global/autodispatched object |
3511
|
|
|
|
|
|
|
sub self { |
3512
|
0
|
0
|
|
0
|
1
|
0
|
@_ > 1 |
3513
|
|
|
|
|
|
|
? $soap = $_[1] |
3514
|
|
|
|
|
|
|
: $soap |
3515
|
|
|
|
|
|
|
} |
3516
|
|
|
|
|
|
|
|
3517
|
|
|
|
|
|
|
# no more warnings about "used only once" |
3518
|
|
|
|
|
|
|
*UNIVERSAL::AUTOLOAD if 0; |
3519
|
|
|
|
|
|
|
|
3520
|
0
|
|
|
0
|
0
|
0
|
sub autodispatched { \&{*UNIVERSAL::AUTOLOAD} eq \&{*SOAP::AUTOLOAD} }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
3521
|
|
|
|
|
|
|
|
3522
|
|
|
|
|
|
|
sub on_debug { |
3523
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
3524
|
0
|
|
|
|
|
0
|
my ($logger) = @_; |
3525
|
|
|
|
|
|
|
#print "DEBUG: self=$self\n"; |
3526
|
|
|
|
|
|
|
#print "DEBUG: logger=$logger\n"; |
3527
|
|
|
|
|
|
|
#print "DEBUG: transport=$self->transport\n"; |
3528
|
|
|
|
|
|
|
#print "DEBUG: Lite.pm: calling setDebugLogger\n"; |
3529
|
0
|
|
|
|
|
0
|
$self->transport->setDebugLogger($logger); |
3530
|
|
|
|
|
|
|
} |
3531
|
|
|
|
|
|
|
|
3532
|
|
|
|
|
|
|
sub soapversion { |
3533
|
51
|
|
|
51
|
1
|
102
|
my $self = shift; |
3534
|
51
|
100
|
|
|
|
547
|
my $version = shift or return $SOAP::Constants::SOAP_VERSION; |
3535
|
|
|
|
|
|
|
|
3536
|
0
|
|
|
|
|
0
|
($version) = grep { |
3537
|
25
|
50
|
|
|
|
339
|
$SOAP::Constants::SOAP_VERSIONS{$_}->{NS_ENV} eq $version |
3538
|
|
|
|
|
|
|
} keys %SOAP::Constants::SOAP_VERSIONS |
3539
|
|
|
|
|
|
|
unless exists $SOAP::Constants::SOAP_VERSIONS{$version}; |
3540
|
|
|
|
|
|
|
|
3541
|
25
|
50
|
33
|
|
|
279
|
die qq!$SOAP::Constants::WRONG_VERSION Supported versions:\n@{[ |
|
0
|
|
|
|
|
0
|
|
3542
|
0
|
|
|
|
|
0
|
join "\n", map {" $_ ($SOAP::Constants::SOAP_VERSIONS{$_}->{NS_ENV})"} keys %SOAP::Constants::SOAP_VERSIONS |
3543
|
|
|
|
|
|
|
]}\n! |
3544
|
|
|
|
|
|
|
unless defined($version) && defined(my $def = $SOAP::Constants::SOAP_VERSIONS{$version}); |
3545
|
|
|
|
|
|
|
|
3546
|
25
|
|
|
|
|
138
|
foreach (keys %$def) { |
3547
|
125
|
|
|
|
|
6922
|
eval "\$SOAP::Constants::$_ = '$SOAP::Constants::SOAP_VERSIONS{$version}->{$_}'"; |
3548
|
|
|
|
|
|
|
} |
3549
|
|
|
|
|
|
|
|
3550
|
25
|
|
|
|
|
644
|
$SOAP::Constants::SOAP_VERSION = $version; |
3551
|
|
|
|
|
|
|
|
3552
|
25
|
|
|
|
|
1201
|
return $self; |
3553
|
|
|
|
|
|
|
} |
3554
|
|
|
|
|
|
|
|
3555
|
25
|
|
|
25
|
|
139
|
BEGIN { SOAP::Lite->soapversion(1.1) } |
3556
|
|
|
|
|
|
|
|
3557
|
|
|
|
|
|
|
sub import { |
3558
|
44
|
|
|
44
|
|
233
|
my $pkg = shift; |
3559
|
44
|
|
|
|
|
108
|
my $caller = caller; |
3560
|
25
|
|
|
25
|
|
138
|
no strict 'refs'; |
|
25
|
|
|
|
|
31
|
|
|
25
|
|
|
|
|
3126
|
|
3561
|
|
|
|
|
|
|
# emulate 'use SOAP::Lite 0.99' behavior |
3562
|
44
|
50
|
66
|
|
|
259
|
$pkg->require_version(shift) if defined $_[0] && $_[0] =~ /^\d/; |
3563
|
|
|
|
|
|
|
|
3564
|
44
|
|
|
|
|
48303
|
while (@_) { |
3565
|
8
|
|
|
|
|
17
|
my $command = shift; |
3566
|
|
|
|
|
|
|
|
3567
|
0
|
|
|
|
|
0
|
my @parameters = UNIVERSAL::isa($_[0] => 'ARRAY') |
3568
|
8
|
50
|
66
|
|
|
89
|
? @{shift()} |
|
|
100
|
|
|
|
|
|
3569
|
|
|
|
|
|
|
: shift |
3570
|
|
|
|
|
|
|
if @_ && $command ne 'autodispatch'; |
3571
|
|
|
|
|
|
|
|
3572
|
8
|
100
|
66
|
|
|
92
|
if ($command eq 'autodispatch' || $command eq 'dispatch_from') { |
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
3573
|
1
|
|
33
|
|
|
6
|
$soap = ($soap||$pkg)->new; |
3574
|
25
|
|
|
25
|
|
130
|
no strict 'refs'; |
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
12906
|
|
3575
|
1
|
50
|
|
|
|
3
|
foreach ($command eq 'autodispatch' |
3576
|
|
|
|
|
|
|
? 'UNIVERSAL' |
3577
|
|
|
|
|
|
|
: @parameters |
3578
|
|
|
|
|
|
|
) { |
3579
|
1
|
|
|
|
|
1
|
my $sub = "${_}::AUTOLOAD"; |
3580
|
1
|
|
|
|
|
9
|
defined &{*$sub} |
|
0
|
|
|
|
|
0
|
|
3581
|
1
|
0
|
|
|
|
1
|
? (\&{*$sub} eq \&{*SOAP::AUTOLOAD} |
|
0
|
50
|
|
|
|
0
|
|
3582
|
|
|
|
|
|
|
? () |
3583
|
|
|
|
|
|
|
: Carp::croak "$sub already assigned and won't work with DISPATCH. Died") |
3584
|
|
|
|
|
|
|
: (*$sub = *SOAP::AUTOLOAD); |
3585
|
|
|
|
|
|
|
} |
3586
|
|
|
|
|
|
|
} |
3587
|
|
|
|
|
|
|
elsif ($command eq 'service') { |
3588
|
0
|
|
|
|
|
0
|
foreach (keys %{SOAP::Schema->schema_url(shift(@parameters))->parse(@parameters)->load->services}) { |
|
0
|
|
|
|
|
0
|
|
3589
|
0
|
|
|
|
|
0
|
$_->export_to_level(1, undef, ':all'); |
3590
|
|
|
|
|
|
|
} |
3591
|
|
|
|
|
|
|
} |
3592
|
|
|
|
|
|
|
elsif ($command eq 'debug' || $command eq 'trace') { |
3593
|
0
|
0
|
|
|
|
0
|
SOAP::Trace->import(@parameters ? @parameters : 'all'); |
3594
|
|
|
|
|
|
|
} |
3595
|
|
|
|
|
|
|
elsif ($command eq 'import') { |
3596
|
0
|
|
|
|
|
0
|
local $^W; # suppress warnings about redefining |
3597
|
0
|
|
|
|
|
0
|
my $package = shift(@parameters); |
3598
|
0
|
0
|
|
|
|
0
|
$package->export_to_level(1, undef, @parameters ? @parameters : ':all') if $package; |
|
|
0
|
|
|
|
|
|
3599
|
|
|
|
|
|
|
} |
3600
|
|
|
|
|
|
|
else { |
3601
|
7
|
50
|
66
|
|
|
38
|
Carp::carp "Odd (wrong?) number of parameters in import(), still continue" if $^W && !(@parameters & 1); |
3602
|
7
|
|
66
|
|
|
108
|
$soap = ($soap||$pkg)->$command(@parameters); |
3603
|
|
|
|
|
|
|
} |
3604
|
|
|
|
|
|
|
} |
3605
|
|
|
|
|
|
|
} |
3606
|
|
|
|
|
|
|
|
3607
|
14
|
|
|
14
|
|
354
|
sub DESTROY { SOAP::Trace::objects('()') } |
3608
|
|
|
|
|
|
|
|
3609
|
|
|
|
|
|
|
sub new { |
3610
|
208
|
|
|
208
|
1
|
1675
|
my $self = shift; |
3611
|
208
|
100
|
|
|
|
562
|
return $self if ref $self; |
3612
|
19
|
50
|
|
|
|
60
|
unless (ref $self) { |
3613
|
19
|
|
|
|
|
34
|
my $class = $self; |
3614
|
|
|
|
|
|
|
# Check whether we can clone. Only the SAME class allowed, no inheritance |
3615
|
|
|
|
|
|
|
$self = ref($soap) eq $class ? $soap->clone : { |
3616
|
|
|
|
|
|
|
_transport => SOAP::Transport->new, |
3617
|
|
|
|
|
|
|
_serializer => SOAP::Serializer->new, |
3618
|
|
|
|
|
|
|
_deserializer => SOAP::Deserializer->new, |
3619
|
|
|
|
|
|
|
_packager => SOAP::Packager::MIME->new, |
3620
|
|
|
|
|
|
|
_schema => undef, |
3621
|
|
|
|
|
|
|
_autoresult => 0, |
3622
|
12
|
|
100
|
12
|
|
150
|
_on_action => sub { sprintf '"%s#%s"', shift || '', shift }, |
3623
|
1
|
50
|
|
1
|
|
4
|
_on_fault => sub {ref $_[1] ? return $_[1] : Carp::croak $_[0]->transport->is_success ? $_[1] : $_[0]->transport->status}, |
|
|
50
|
|
|
|
|
|
3624
|
19
|
100
|
|
|
|
192
|
}; |
3625
|
19
|
|
|
|
|
58
|
bless $self => $class; |
3626
|
19
|
|
66
|
|
|
82
|
$self->on_nonserialized($self->on_nonserialized || $self->serializer->on_nonserialized); |
3627
|
19
|
|
|
|
|
51
|
SOAP::Trace::objects('()'); |
3628
|
|
|
|
|
|
|
} |
3629
|
|
|
|
|
|
|
|
3630
|
19
|
50
|
66
|
|
|
96
|
Carp::carp "Odd (wrong?) number of parameters in new()" if $^W && (@_ & 1); |
3631
|
25
|
|
|
25
|
|
178
|
no strict qw(refs); |
|
25
|
|
|
|
|
78
|
|
|
25
|
|
|
|
|
6433
|
|
3632
|
19
|
|
|
|
|
67
|
while (@_) { |
3633
|
3
|
|
|
|
|
7
|
my($method, $params) = splice(@_,0,2); |
3634
|
3
|
50
|
0
|
|
|
30
|
$self->can($method) |
|
|
50
|
|
|
|
|
|
3635
|
|
|
|
|
|
|
? $self->$method(ref $params eq 'ARRAY' ? @$params : $params) |
3636
|
|
|
|
|
|
|
: $^W && Carp::carp "Unrecognized parameter '$method' in new()" |
3637
|
|
|
|
|
|
|
} |
3638
|
|
|
|
|
|
|
|
3639
|
19
|
|
|
|
|
44
|
return $self; |
3640
|
|
|
|
|
|
|
} |
3641
|
|
|
|
|
|
|
|
3642
|
|
|
|
|
|
|
sub init_context { |
3643
|
12
|
|
|
12
|
0
|
36
|
my $self = shift->new; |
3644
|
12
|
|
|
|
|
76
|
$self->{'_deserializer'}->{'_context'} = $self; |
3645
|
|
|
|
|
|
|
# weaken circular reference to avoid a memory hole |
3646
|
12
|
|
|
|
|
77
|
weaken $self->{'_deserializer'}->{'_context'}; |
3647
|
|
|
|
|
|
|
|
3648
|
12
|
|
|
|
|
36
|
$self->{'_serializer'}->{'_context'} = $self; |
3649
|
|
|
|
|
|
|
# weaken circular reference to avoid a memory hole |
3650
|
12
|
|
|
|
|
51
|
weaken $self->{'_serializer'}->{'_context'}; |
3651
|
|
|
|
|
|
|
} |
3652
|
|
|
|
|
|
|
|
3653
|
|
|
|
|
|
|
# Naming? wsdl_parser |
3654
|
|
|
|
|
|
|
sub schema { |
3655
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
3656
|
0
|
0
|
|
|
|
0
|
if (@_) { |
3657
|
0
|
|
|
|
|
0
|
$self->{'_schema'} = shift; |
3658
|
0
|
|
|
|
|
0
|
return $self; |
3659
|
|
|
|
|
|
|
} |
3660
|
|
|
|
|
|
|
else { |
3661
|
0
|
0
|
|
|
|
0
|
if (!defined $self->{'_schema'}) { |
3662
|
0
|
|
|
|
|
0
|
$self->{'_schema'} = SOAP::Schema->new; |
3663
|
|
|
|
|
|
|
} |
3664
|
0
|
|
|
|
|
0
|
return $self->{'_schema'}; |
3665
|
|
|
|
|
|
|
} |
3666
|
|
|
|
|
|
|
} |
3667
|
|
|
|
|
|
|
|
3668
|
|
|
|
|
|
|
sub BEGIN { |
3669
|
25
|
|
|
25
|
|
127
|
no strict 'refs'; |
|
25
|
|
|
|
|
108
|
|
|
25
|
|
|
|
|
5960
|
|
3670
|
25
|
|
|
25
|
|
66
|
for my $method (qw(serializer deserializer)) { |
3671
|
50
|
|
|
|
|
95
|
my $field = '_' . $method; |
3672
|
|
|
|
|
|
|
*$method = sub { |
3673
|
52
|
|
|
52
|
|
157
|
my $self = shift->new; |
3674
|
52
|
50
|
|
|
|
147
|
if (@_) { |
3675
|
0
|
|
|
|
|
0
|
my $context = $self->{$field}->{'_context'}; # save the old context |
3676
|
0
|
|
|
|
|
0
|
$self->{$field} = shift; |
3677
|
0
|
|
|
|
|
0
|
$self->{$field}->{'_context'} = $context; # restore the old context |
3678
|
0
|
|
|
|
|
0
|
return $self; |
3679
|
|
|
|
|
|
|
} |
3680
|
|
|
|
|
|
|
else { |
3681
|
52
|
|
|
|
|
276
|
return $self->{$field}; |
3682
|
|
|
|
|
|
|
} |
3683
|
|
|
|
|
|
|
} |
3684
|
50
|
|
|
|
|
333
|
} |
3685
|
|
|
|
|
|
|
|
3686
|
|
|
|
|
|
|
__PACKAGE__->__mk_accessors( |
3687
|
25
|
|
|
|
|
162
|
qw(endpoint transport outputxml autoresult packager) |
3688
|
|
|
|
|
|
|
); |
3689
|
|
|
|
|
|
|
# for my $method () { |
3690
|
|
|
|
|
|
|
# my $field = '_' . $method; |
3691
|
|
|
|
|
|
|
# *$method = sub { |
3692
|
|
|
|
|
|
|
# my $self = shift->new; |
3693
|
|
|
|
|
|
|
# @_ ? ($self->{$field} = shift, return $self) : return $self->{$field}; |
3694
|
|
|
|
|
|
|
# } |
3695
|
|
|
|
|
|
|
# } |
3696
|
25
|
|
|
|
|
41
|
for my $method (qw(on_action on_fault on_nonserialized)) { |
3697
|
75
|
|
|
|
|
112
|
my $field = '_' . $method; |
3698
|
|
|
|
|
|
|
*$method = sub { |
3699
|
90
|
|
|
90
|
|
272
|
my $self = shift->new; |
3700
|
90
|
100
|
|
|
|
653
|
return $self->{$field} unless @_; |
3701
|
35
|
|
|
|
|
58
|
local $@; |
3702
|
|
|
|
|
|
|
# commented out because that 'eval' was unsecure |
3703
|
|
|
|
|
|
|
# > ref $_[0] eq 'CODE' ? shift : eval shift; |
3704
|
|
|
|
|
|
|
# Am I paranoid enough? |
3705
|
35
|
|
|
|
|
81
|
$self->{$field} = shift; |
3706
|
35
|
50
|
|
|
|
154
|
Carp::croak $@ if $@; |
3707
|
35
|
50
|
|
|
|
142
|
Carp::croak "$method() expects subroutine (CODE) or string that evaluates into subroutine (CODE)" |
3708
|
|
|
|
|
|
|
unless ref $self->{$field} eq 'CODE'; |
3709
|
35
|
|
|
|
|
295
|
return $self; |
3710
|
|
|
|
|
|
|
} |
3711
|
75
|
|
|
|
|
319
|
} |
3712
|
|
|
|
|
|
|
# SOAP::Transport Shortcuts |
3713
|
|
|
|
|
|
|
# TODO - deprecate proxy() in favor of new language endpoint_url() |
3714
|
25
|
|
|
25
|
|
127
|
no strict qw(refs); |
|
25
|
|
|
|
|
32
|
|
|
25
|
|
|
|
|
5197
|
|
3715
|
25
|
|
|
|
|
51
|
for my $method (qw(proxy)) { |
3716
|
|
|
|
|
|
|
*$method = sub { |
3717
|
37
|
|
|
37
|
|
99
|
my $self = shift->new; |
3718
|
37
|
100
|
|
|
|
193
|
@_ ? ($self->transport->$method(@_), return $self) : return $self->transport->$method(); |
3719
|
|
|
|
|
|
|
} |
3720
|
25
|
|
|
|
|
123
|
} |
3721
|
|
|
|
|
|
|
|
3722
|
|
|
|
|
|
|
# SOAP::Seriailizer Shortcuts |
3723
|
25
|
|
|
|
|
48
|
for my $method (qw(autotype readable envprefix encodingStyle |
3724
|
|
|
|
|
|
|
encprefix multirefinplace encoding |
3725
|
|
|
|
|
|
|
typelookup header maptype xmlschema |
3726
|
|
|
|
|
|
|
uri ns_prefix ns_uri use_prefix use_default_ns |
3727
|
|
|
|
|
|
|
ns default_ns)) { |
3728
|
|
|
|
|
|
|
*$method = sub { |
3729
|
14
|
|
|
14
|
|
125
|
my $self = shift->new; |
3730
|
14
|
100
|
|
|
|
95
|
@_ ? ($self->serializer->$method(@_), return $self) : return $self->serializer->$method(); |
3731
|
|
|
|
|
|
|
} |
3732
|
450
|
|
|
|
|
2538
|
} |
3733
|
|
|
|
|
|
|
|
3734
|
|
|
|
|
|
|
# SOAP::Schema Shortcuts |
3735
|
25
|
|
|
|
|
47
|
for my $method (qw(cache_dir cache_ttl)) { |
3736
|
|
|
|
|
|
|
*$method = sub { |
3737
|
0
|
|
|
0
|
|
0
|
my $self = shift->new; |
3738
|
0
|
0
|
|
|
|
0
|
@_ ? ($self->schema->$method(@_), return $self) : return $self->schema->$method(); |
3739
|
|
|
|
|
|
|
} |
3740
|
50
|
|
|
|
|
5864
|
} |
3741
|
|
|
|
|
|
|
} |
3742
|
|
|
|
|
|
|
|
3743
|
|
|
|
|
|
|
sub parts { |
3744
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
3745
|
0
|
|
|
|
|
0
|
$self->packager->parts(@_); |
3746
|
0
|
|
|
|
|
0
|
return $self; |
3747
|
|
|
|
|
|
|
} |
3748
|
|
|
|
|
|
|
|
3749
|
|
|
|
|
|
|
# Naming? wsdl |
3750
|
|
|
|
|
|
|
sub service { |
3751
|
0
|
|
|
0
|
1
|
0
|
my $self = shift->new; |
3752
|
0
|
0
|
|
|
|
0
|
return $self->{'_service'} unless @_; |
3753
|
0
|
|
|
|
|
0
|
$self->schema->schema_url($self->{'_service'} = shift); |
3754
|
0
|
|
|
|
|
0
|
my %services = %{$self->schema->parse(@_)->load->services}; |
|
0
|
|
|
|
|
0
|
|
3755
|
|
|
|
|
|
|
|
3756
|
0
|
0
|
|
|
|
0
|
Carp::croak "More than one service in service description. Service and port names have to be specified\n" |
3757
|
|
|
|
|
|
|
if keys %services > 1; |
3758
|
0
|
|
|
|
|
0
|
my $service = (keys %services)[0]->new; |
3759
|
0
|
|
|
|
|
0
|
return $service; |
3760
|
|
|
|
|
|
|
} |
3761
|
|
|
|
|
|
|
|
3762
|
|
|
|
|
|
|
sub AUTOLOAD { |
3763
|
11
|
|
|
11
|
|
155
|
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); |
3764
|
11
|
50
|
|
|
|
49
|
return if $method eq 'DESTROY'; |
3765
|
|
|
|
|
|
|
|
3766
|
11
|
50
|
|
|
|
39
|
ref $_[0] or Carp::croak qq!Can\'t locate class method "$method" via package \"! . __PACKAGE__ .'\"'; |
3767
|
|
|
|
|
|
|
|
3768
|
25
|
|
|
25
|
|
133
|
no strict 'refs'; |
|
25
|
|
|
|
|
34
|
|
|
25
|
|
|
|
|
23825
|
|
3769
|
|
|
|
|
|
|
*$AUTOLOAD = sub { |
3770
|
11
|
|
|
11
|
|
29
|
my $self = shift; |
3771
|
11
|
|
|
|
|
54
|
my $som = $self->call($method => @_); |
3772
|
11
|
0
|
33
|
|
|
102
|
return $self->autoresult && UNIVERSAL::isa($som => 'SOAP::SOM') |
|
|
50
|
|
|
|
|
|
3773
|
|
|
|
|
|
|
? wantarray ? $som->paramsall : $som->result |
3774
|
|
|
|
|
|
|
: $som; |
3775
|
11
|
|
|
|
|
82
|
}; |
3776
|
11
|
|
|
|
|
130
|
goto &$AUTOLOAD; |
3777
|
|
|
|
|
|
|
} |
3778
|
|
|
|
|
|
|
|
3779
|
|
|
|
|
|
|
sub call { |
3780
|
12
|
|
|
12
|
1
|
53
|
SOAP::Trace::trace('()'); |
3781
|
12
|
|
|
|
|
22
|
my $self = shift; |
3782
|
|
|
|
|
|
|
|
3783
|
12
|
50
|
33
|
|
|
43
|
die "A service address has not been specified either by using SOAP::Lite->proxy() or a service description)\n" |
3784
|
|
|
|
|
|
|
unless defined $self->proxy && UNIVERSAL::isa($self->proxy => 'SOAP::Client'); |
3785
|
|
|
|
|
|
|
|
3786
|
12
|
|
|
|
|
65
|
$self->init_context(); |
3787
|
|
|
|
|
|
|
|
3788
|
12
|
|
|
|
|
47
|
my $serializer = $self->serializer; |
3789
|
12
|
|
|
|
|
57
|
$serializer->on_nonserialized($self->on_nonserialized); |
3790
|
|
|
|
|
|
|
|
3791
|
12
|
|
|
|
|
47
|
my $response = $self->transport->send_receive( |
3792
|
|
|
|
|
|
|
context => $self, # this is provided for context |
3793
|
|
|
|
|
|
|
endpoint => $self->endpoint, |
3794
|
|
|
|
|
|
|
action => scalar($self->on_action->($serializer->uriformethod($_[0]))), |
3795
|
|
|
|
|
|
|
# leave only parameters so we can later update them if required |
3796
|
|
|
|
|
|
|
envelope => $serializer->envelope(method => shift, @_), |
3797
|
|
|
|
|
|
|
encoding => $serializer->encoding, |
3798
|
12
|
50
|
|
|
|
40
|
parts => @{$self->packager->parts} ? $self->packager->parts : undef, |
3799
|
|
|
|
|
|
|
); |
3800
|
|
|
|
|
|
|
|
3801
|
12
|
50
|
|
|
|
685
|
return $response if $self->outputxml; |
3802
|
|
|
|
|
|
|
|
3803
|
12
|
50
|
|
|
|
60
|
my $result = eval { $self->deserializer->deserialize($response) } |
|
12
|
|
|
|
|
66
|
|
3804
|
|
|
|
|
|
|
if $response; |
3805
|
|
|
|
|
|
|
|
3806
|
12
|
50
|
66
|
|
|
126
|
if (!$self->transport->is_success || # transport fault |
|
|
|
0
|
|
|
|
|
|
|
|
33
|
|
|
|
|
3807
|
|
|
|
|
|
|
$@ || # not deserializible |
3808
|
|
|
|
|
|
|
# fault message even if transport OK |
3809
|
|
|
|
|
|
|
# or no transport error (for example, fo TCP, POP3, IO implementations) |
3810
|
|
|
|
|
|
|
UNIVERSAL::isa($result => 'SOAP::SOM') && $result->fault) { |
3811
|
12
|
|
33
|
|
|
132
|
return ($self->on_fault->($self, $@ |
3812
|
|
|
|
|
|
|
? $@ . ($response || '') |
3813
|
|
|
|
|
|
|
: $result) |
3814
|
|
|
|
|
|
|
|| $result |
3815
|
|
|
|
|
|
|
); |
3816
|
|
|
|
|
|
|
# ? # trick editors |
3817
|
|
|
|
|
|
|
} |
3818
|
|
|
|
|
|
|
# this might be trouble for connection close... |
3819
|
0
|
0
|
|
|
|
|
return unless $response; # nothing to do for one-ways |
3820
|
|
|
|
|
|
|
|
3821
|
|
|
|
|
|
|
# little bit tricky part that binds in/out parameters |
3822
|
0
|
0
|
0
|
|
|
|
if (UNIVERSAL::isa($result => 'SOAP::SOM') |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
3823
|
|
|
|
|
|
|
&& ($result->paramsout || $result->headers) |
3824
|
|
|
|
|
|
|
&& $serializer->signature) { |
3825
|
0
|
|
|
|
|
|
my $num = 0; |
3826
|
0
|
|
|
|
|
|
my %signatures = map {$_ => $num++} @{$serializer->signature}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
3827
|
0
|
|
|
|
|
|
for ($result->dataof(SOAP::SOM::paramsout), $result->dataof(SOAP::SOM::headers)) { |
3828
|
0
|
|
0
|
|
|
|
my $signature = join $;, $_->name, $_->type || ''; |
3829
|
0
|
0
|
|
|
|
|
if (exists $signatures{$signature}) { |
3830
|
0
|
|
|
|
|
|
my $param = $signatures{$signature}; |
3831
|
0
|
|
|
|
|
|
my($value) = $_->value; # take first value |
3832
|
|
|
|
|
|
|
|
3833
|
|
|
|
|
|
|
# fillup parameters |
3834
|
0
|
|
|
|
|
|
UNIVERSAL::isa($_[$param] => 'SOAP::Data') |
3835
|
|
|
|
|
|
|
? $_[$param]->SOAP::Data::value($value) |
3836
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[$param] => 'ARRAY') |
3837
|
0
|
|
|
|
|
|
? (@{$_[$param]} = @$value) |
3838
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[$param] => 'HASH') |
3839
|
0
|
|
|
|
|
|
? (%{$_[$param]} = %$value) |
3840
|
|
|
|
|
|
|
: UNIVERSAL::isa($_[$param] => 'SCALAR') |
3841
|
0
|
0
|
|
|
|
|
? (${$_[$param]} = $$value) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
3842
|
|
|
|
|
|
|
: ($_[$param] = $value) |
3843
|
|
|
|
|
|
|
} |
3844
|
|
|
|
|
|
|
} |
3845
|
|
|
|
|
|
|
} |
3846
|
0
|
|
|
|
|
|
return $result; |
3847
|
|
|
|
|
|
|
} # end of call() |
3848
|
|
|
|
|
|
|
|
3849
|
|
|
|
|
|
|
# ====================================================================== |
3850
|
|
|
|
|
|
|
|
3851
|
|
|
|
|
|
|
package SOAP::Lite::COM; |
3852
|
|
|
|
|
|
|
|
3853
|
|
|
|
|
|
|
require SOAP::Lite; |
3854
|
|
|
|
|
|
|
|
3855
|
|
|
|
|
|
|
sub required { |
3856
|
0
|
|
|
0
|
|
|
foreach (qw( |
3857
|
|
|
|
|
|
|
URI::_foreign URI::http URI::https |
3858
|
|
|
|
|
|
|
LWP::Protocol::http LWP::Protocol::https LWP::Authen::Basic LWP::Authen::Digest |
3859
|
|
|
|
|
|
|
HTTP::Daemon Compress::Zlib SOAP::Transport::HTTP |
3860
|
|
|
|
|
|
|
XMLRPC::Lite XMLRPC::Transport::HTTP |
3861
|
|
|
|
|
|
|
)) { |
3862
|
0
|
|
|
|
|
|
eval join ';', 'local $SIG{__DIE__}', "require $_"; |
3863
|
|
|
|
|
|
|
} |
3864
|
|
|
|
|
|
|
} |
3865
|
|
|
|
|
|
|
|
3866
|
0
|
|
|
0
|
|
|
sub new { required; SOAP::Lite->new(@_) } |
|
0
|
|
|
|
|
|
|
3867
|
|
|
|
|
|
|
|
3868
|
|
|
|
|
|
|
sub create; *create = \&new; # make alias. Somewhere 'new' is registered keyword |
3869
|
|
|
|
|
|
|
|
3870
|
|
|
|
|
|
|
sub soap; *soap = \&new; # also alias. Just to be consistent with .xmlrpc call |
3871
|
|
|
|
|
|
|
|
3872
|
0
|
|
|
0
|
|
|
sub xmlrpc { required; XMLRPC::Lite->new(@_) } |
|
0
|
|
|
|
|
|
|
3873
|
|
|
|
|
|
|
|
3874
|
0
|
|
|
0
|
|
|
sub server { required; shift->new(@_) } |
|
0
|
|
|
|
|
|
|
3875
|
|
|
|
|
|
|
|
3876
|
0
|
|
|
0
|
|
|
sub data { SOAP::Data->new(@_) } |
3877
|
|
|
|
|
|
|
|
3878
|
0
|
|
|
0
|
|
|
sub header { SOAP::Header->new(@_) } |
3879
|
|
|
|
|
|
|
|
3880
|
0
|
|
|
0
|
|
|
sub hash { +{@_} } |
3881
|
|
|
|
|
|
|
|
3882
|
|
|
|
|
|
|
sub instanceof { |
3883
|
0
|
|
|
0
|
|
|
my $class = shift; |
3884
|
0
|
0
|
|
|
|
|
die "Incorrect class name" unless $class =~ /^(\w[\w:]*)$/; |
3885
|
0
|
|
|
|
|
|
eval "require $class"; |
3886
|
0
|
|
|
|
|
|
$class->new(@_); |
3887
|
|
|
|
|
|
|
} |
3888
|
|
|
|
|
|
|
|
3889
|
|
|
|
|
|
|
# ====================================================================== |
3890
|
|
|
|
|
|
|
|
3891
|
|
|
|
|
|
|
1; |
3892
|
|
|
|
|
|
|
|
3893
|
|
|
|
|
|
|
__END__ |