line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
|
|
|
|
|
|
package SOAP::WSDL::XSD::Typelib::ComplexType; |
3
|
12
|
|
|
12
|
|
34012
|
use strict; |
|
12
|
|
|
|
|
12
|
|
|
12
|
|
|
|
|
311
|
|
4
|
12
|
|
|
12
|
|
36
|
use warnings; |
|
12
|
|
|
|
|
16
|
|
|
12
|
|
|
|
|
201
|
|
5
|
12
|
|
|
12
|
|
32
|
use Carp; |
|
12
|
|
|
|
|
12
|
|
|
12
|
|
|
|
|
602
|
|
6
|
12
|
|
|
12
|
|
3608
|
use SOAP::WSDL::XSD::Typelib::Builtin; |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
264
|
|
7
|
12
|
|
|
12
|
|
40
|
use Scalar::Util qw(blessed); |
|
12
|
|
|
|
|
10
|
|
|
12
|
|
|
|
|
536
|
|
8
|
12
|
|
|
12
|
|
5938
|
use Data::Dumper; |
|
12
|
|
|
|
|
51289
|
|
|
12
|
|
|
|
|
691
|
|
9
|
|
|
|
|
|
|
require Class::Std::Fast::Storable; |
10
|
12
|
|
|
12
|
|
4687
|
use Class::Load (); |
|
12
|
|
|
|
|
220900
|
|
|
12
|
|
|
|
|
296
|
|
11
|
|
|
|
|
|
|
|
12
|
12
|
|
|
12
|
|
68
|
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); |
|
12
|
|
|
|
|
13
|
|
|
12
|
|
|
|
|
4480
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our $VERSION = 3.003; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# remove in 2.1 |
17
|
|
|
|
|
|
|
our $AS_HASH_REF_WITHOUT_ATTRIBUTES = 0; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my %ELEMENT_FORM_QUALIFIED_OF; # denotes whether elements are qualified |
20
|
|
|
|
|
|
|
my %ELEMENTS_FROM; # order of elements in a class |
21
|
|
|
|
|
|
|
my %ATTRIBUTES_OF; # references to value hashes |
22
|
|
|
|
|
|
|
my %CLASSES_OF; # class names of elements in a class |
23
|
|
|
|
|
|
|
my %NAMES_OF; # XML names of elements in a class |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# XML Attribute handling |
27
|
|
|
|
|
|
|
my %xml_attr_of :ATTR(); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Namespace handling |
30
|
|
|
|
|
|
|
my %xmlns_of :ATTR(); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# don't you ever dare to use this ! |
33
|
|
|
|
|
|
|
our $___attributes_of_ref = \%ATTRIBUTES_OF; |
34
|
|
|
|
|
|
|
our $___xml_attribute_of_ref = \%xml_attr_of; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# STORABLE_ methods for supporting Class::Std::Fast::Storable. |
37
|
|
|
|
|
|
|
# We could also handle them via AUTOMETHOD, |
38
|
|
|
|
|
|
|
# but AUTOMETHOD should always croak... |
39
|
|
|
|
|
|
|
# Actually, AUTOMETHOD is faster (~1%) if Class::Std::Fast is loaded |
40
|
|
|
|
|
|
|
# properly, and slower (~10%) if not. |
41
|
|
|
|
|
|
|
# Hmmm. Trade 1% for 10? |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my %STORABLE_METHODS = ( |
44
|
|
|
|
|
|
|
STORABLE_freeze_pre => undef, |
45
|
|
|
|
|
|
|
STORABLE_freeze_post => undef, |
46
|
|
|
|
|
|
|
STORABLE_thaw_pre => undef, |
47
|
|
|
|
|
|
|
STORABLE_thaw_post => undef, |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# for error reporting. Eases working with data objects... |
51
|
|
|
|
|
|
|
sub AUTOMETHOD { |
52
|
|
|
|
|
|
|
# return before unpacking @_ for speed reasons |
53
|
16
|
50
|
|
16
|
0
|
3840
|
return if exists $STORABLE_METHODS{$_}; |
54
|
|
|
|
|
|
|
|
55
|
16
|
|
|
|
|
19
|
my ($self, $ident, @args_from) = @_; |
56
|
16
|
100
|
100
|
|
|
48
|
my $class = ref $self || $self or die "Cannot call AUTOMETHOD as function"; |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Test whether we're called from ->can() |
59
|
15
|
|
|
|
|
50
|
my @caller = caller(1); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# return if not called by AUTOLOAD - caller must be something like can() |
62
|
|
|
|
|
|
|
# Unfortunately we cannot test for "UNIVERSAL::can", as it gets overwritten |
63
|
|
|
|
|
|
|
# by both Class::Std and Class::Std::Fast, and we don't know the loading |
64
|
|
|
|
|
|
|
# order (Class::Std::Fast should be loaded before for maximum speedup) |
65
|
15
|
100
|
|
|
|
43
|
return if $caller[3] ne 'Class::Std::AUTOLOAD'; |
66
|
|
|
|
|
|
|
|
67
|
3
|
|
|
|
|
153
|
confess "Can't locate object method \"$_\" via package \"$class\". \n" |
68
|
|
|
|
|
|
|
. "Valid methods are: " |
69
|
3
|
|
|
|
|
10
|
. join(', ', map { ("get_$_" , "set_$_") } keys %{ $ATTRIBUTES_OF{ $class } }) |
|
3
|
|
|
|
|
14
|
|
70
|
|
|
|
|
|
|
. "\n" |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub attr { |
74
|
|
|
|
|
|
|
# We're working on @_ for speed. |
75
|
|
|
|
|
|
|
# Normally, the first line would look like this: |
76
|
|
|
|
|
|
|
# my $self = shift; |
77
|
|
|
|
|
|
|
|
78
|
11
|
100
|
|
11
|
1
|
1102
|
my $class = $_[0]->__get_attr_class() |
79
|
|
|
|
|
|
|
or return; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# pass arguments to attributes constructor (if any); |
82
|
|
|
|
|
|
|
# lets attr($foo) work as setter |
83
|
10
|
100
|
|
|
|
40
|
if ($_[1]) { |
84
|
3
|
|
|
|
|
10
|
return $xml_attr_of{ ${$_[0]} } = $class->new($_[1]); |
|
3
|
|
|
|
|
12
|
|
85
|
|
|
|
|
|
|
} |
86
|
7
|
100
|
|
|
|
10
|
return $xml_attr_of{ ${$_[0]} } if exists $xml_attr_of{ ${$_[0]} }; |
|
5
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
148
|
|
87
|
2
|
|
|
|
|
7
|
return $xml_attr_of{ ${$_[0]} } = $class->new(); |
|
2
|
|
|
|
|
8
|
|
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub serialize_attr { |
91
|
10
|
100
|
|
10
|
1
|
11
|
return q{} if not $xml_attr_of{ ${ $_[0] } }; |
|
10
|
|
|
|
|
93
|
|
92
|
3
|
|
|
|
|
5
|
return $xml_attr_of{ ${ $_[0] } }->serialize(); |
|
3
|
|
|
|
|
10
|
|
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# TODO: are complextypes are always true ? |
96
|
12
|
|
|
12
|
1
|
58
|
sub as_bool :BOOLIFY { 1 } |
|
12
|
|
|
7
|
|
19
|
|
|
12
|
|
|
|
|
78
|
|
|
7
|
|
|
|
|
140
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub as_hash_ref { |
99
|
|
|
|
|
|
|
# we're working on $_[0] for speed (as always...) |
100
|
|
|
|
|
|
|
# |
101
|
|
|
|
|
|
|
# Normally the first line would read: |
102
|
|
|
|
|
|
|
# my ($self, $ignore_attributes) = @_; |
103
|
|
|
|
|
|
|
# |
104
|
21
|
|
|
21
|
1
|
2070
|
my $attributes_ref = $ATTRIBUTES_OF{ ref $_[0] }; |
105
|
|
|
|
|
|
|
|
106
|
21
|
|
|
|
|
26
|
my $hash_of_ref = {}; |
107
|
21
|
100
|
|
|
|
289
|
if ($_[0]->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType')) { |
108
|
4
|
|
|
|
|
9
|
$hash_of_ref->{ value } = $_[0]->get_value(); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
else { |
111
|
17
|
|
|
|
|
17
|
foreach my $attribute (keys %{ $attributes_ref }) { |
|
17
|
|
|
|
|
41
|
|
112
|
18
|
100
|
|
|
|
89
|
next if not defined $attributes_ref->{ $attribute }->{ ${ $_[0] } }; |
|
18
|
|
|
|
|
37
|
|
113
|
17
|
|
|
|
|
20
|
my $value = $attributes_ref->{ $attribute }->{ ${ $_[0] } }; |
|
17
|
|
|
|
|
16
|
|
114
|
|
|
|
|
|
|
|
115
|
10
|
100
|
|
|
|
43
|
$hash_of_ref->{ $attribute } = blessed $value |
116
|
|
|
|
|
|
|
? $value->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') |
117
|
|
|
|
|
|
|
? $value->get_value() |
118
|
|
|
|
|
|
|
: $value->as_hash_ref($_[1]) |
119
|
|
|
|
|
|
|
: ref $value eq 'ARRAY' |
120
|
|
|
|
|
|
|
? [ |
121
|
|
|
|
|
|
|
map { |
122
|
5
|
|
|
|
|
8
|
$_->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') |
123
|
|
|
|
|
|
|
? $_->get_value() |
124
|
|
|
|
|
|
|
: $_->as_hash_ref($_[1]) |
125
|
17
|
100
|
|
|
|
80
|
} @{ $value } |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
126
|
|
|
|
|
|
|
] |
127
|
|
|
|
|
|
|
: die "Neither blessed obj nor list ref"; |
128
|
|
|
|
|
|
|
}; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# $AS_HASH_REF_WITHOUT_ATTRIBUTES is deprecated by NOW and will be removed |
132
|
|
|
|
|
|
|
# in 2.1 |
133
|
21
|
100
|
66
|
|
|
117
|
return $hash_of_ref if $_[1] or $AS_HASH_REF_WITHOUT_ATTRIBUTES; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
|
136
|
18
|
100
|
|
|
|
17
|
if (exists $xml_attr_of{ ${ $_[0] } }) { |
|
18
|
|
|
|
|
38
|
|
137
|
5
|
|
|
|
|
5
|
$hash_of_ref->{ xmlattr } = $xml_attr_of{ ${ $_[0] } }->as_hash_ref(); |
|
5
|
|
|
|
|
15
|
|
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
18
|
|
|
|
|
45
|
return $hash_of_ref; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# we store per-class elements. |
144
|
|
|
|
|
|
|
# call as __PACKAGE__->_factory |
145
|
|
|
|
|
|
|
sub _factory { |
146
|
32
|
|
|
32
|
|
9138
|
my $class = shift; |
147
|
32
|
|
|
|
|
90
|
$ELEMENTS_FROM{ $class } = shift; |
148
|
32
|
|
|
|
|
38
|
$ATTRIBUTES_OF{ $class } = shift; |
149
|
32
|
|
|
|
|
39
|
$CLASSES_OF{ $class } = shift; |
150
|
32
|
|
|
|
|
37
|
$NAMES_OF{ $class } = shift; |
151
|
|
|
|
|
|
|
|
152
|
12
|
|
|
12
|
|
5014
|
no strict qw(refs); |
|
12
|
|
|
|
|
18
|
|
|
12
|
|
|
|
|
279
|
|
153
|
12
|
|
|
12
|
|
41
|
no warnings qw(redefine); |
|
12
|
|
|
|
|
12
|
|
|
12
|
|
|
|
|
12242
|
|
154
|
|
|
|
|
|
|
|
155
|
32
|
|
|
|
|
32
|
while (my ($name, $attribute_ref) = each %{ $ATTRIBUTES_OF{ $class } } ) { |
|
95
|
|
|
|
|
265
|
|
156
|
65
|
100
|
|
|
|
135
|
my $type = $CLASSES_OF{ $class }->{ $name } |
157
|
|
|
|
|
|
|
or croak "No class given for $name"; |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# require all types here |
160
|
|
|
|
|
|
|
Class::Load::is_class_loaded($type) |
161
|
64
|
100
|
100
|
|
|
134
|
or eval { Class::Load::load_class $type } |
|
2
|
|
|
|
|
83
|
|
162
|
|
|
|
|
|
|
or croak $@; |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# check now, so we don't need to do it later. |
165
|
|
|
|
|
|
|
# $is_list is used in the methods created. Filling it now means |
166
|
|
|
|
|
|
|
# we don't have to check it every time the method is called, but |
167
|
|
|
|
|
|
|
# can just use $is_list, which will hold the value assigned to |
168
|
|
|
|
|
|
|
# it when the method was created. |
169
|
63
|
|
|
|
|
2472
|
my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list'); |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# The set_$name method below looks rather weird, |
172
|
|
|
|
|
|
|
# but is optimized for performance. |
173
|
|
|
|
|
|
|
# |
174
|
|
|
|
|
|
|
# We could use sub calls for sure, but these are much slower. And |
175
|
|
|
|
|
|
|
# the logic is not that easy: |
176
|
|
|
|
|
|
|
# |
177
|
|
|
|
|
|
|
# we accept: |
178
|
|
|
|
|
|
|
# a) objects |
179
|
|
|
|
|
|
|
# b) scalars |
180
|
|
|
|
|
|
|
# c) list refs |
181
|
|
|
|
|
|
|
# d) hash refs |
182
|
|
|
|
|
|
|
# e) mixed stuff of all of the above, so we have to set our child to |
183
|
|
|
|
|
|
|
# a) value if it's an object |
184
|
|
|
|
|
|
|
# b) New object of expected class with value for simple values |
185
|
|
|
|
|
|
|
# c 1) New object with value for list values and list type |
186
|
|
|
|
|
|
|
# c 2) List ref of new objects with value for list values and |
187
|
|
|
|
|
|
|
# non-list type |
188
|
|
|
|
|
|
|
# c + e 1) List ref of objects for list values (list of objects) |
189
|
|
|
|
|
|
|
# and non-list type |
190
|
|
|
|
|
|
|
# c + e 2) List ref of new objects for list values (list of hashes) |
191
|
|
|
|
|
|
|
# and non-list type where the hash ref is passed to new as |
192
|
|
|
|
|
|
|
# argument |
193
|
|
|
|
|
|
|
# d) New object with values passed to new for HASH references |
194
|
|
|
|
|
|
|
# |
195
|
|
|
|
|
|
|
# We throw an error on |
196
|
|
|
|
|
|
|
# a) list refs of list refs - don't know what to do with this (maybe |
197
|
|
|
|
|
|
|
# use for lists of list types ?) |
198
|
|
|
|
|
|
|
# b) wrong object types |
199
|
|
|
|
|
|
|
# c) non-blessed non-ARRAY/HASH references - if you can define semantics |
200
|
|
|
|
|
|
|
# for GLOB or SCALAR references, feel free to add them. |
201
|
|
|
|
|
|
|
# d) we should also die for non-blessed non-ARRAY/HASH references in |
202
|
|
|
|
|
|
|
# lists but don't do yet - oh my ! |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
# keep in sync with Generator::Template::Plugin::XSD - maybe use |
205
|
|
|
|
|
|
|
# function to allow substituting via symbol table... |
206
|
63
|
|
|
|
|
57
|
my $method_name = $name; |
207
|
63
|
|
|
|
|
286
|
$method_name =~s{[\.\-]}{_}xmsg; |
208
|
63
|
|
|
|
|
225
|
*{ "$class\::set_$method_name" } = sub { |
209
|
31
|
100
|
|
31
|
|
399
|
if (not $#_) { |
210
|
1
|
|
|
|
|
2
|
delete $attribute_ref->{ ${ $_[0] } }; |
|
1
|
|
|
|
|
7
|
|
211
|
1
|
|
|
|
|
122
|
return; |
212
|
|
|
|
|
|
|
}; |
213
|
30
|
|
|
|
|
43
|
my $is_ref = ref $_[1]; |
214
|
28
|
100
|
|
|
|
1073
|
$attribute_ref->{ ${ $_[0] } } = ($is_ref) |
|
14
|
50
|
|
|
|
76
|
|
|
|
100
|
|
|
|
|
|
215
|
|
|
|
|
|
|
? ($is_ref eq 'ARRAY') |
216
|
|
|
|
|
|
|
? $is_list # remembered from outside closure |
217
|
|
|
|
|
|
|
? $type->new({ value => $_[1] }) # it's a list element - can take list ref as value |
218
|
|
|
|
|
|
|
: [ map { # it's not a list element - set value to list of objects |
219
|
7
|
|
|
|
|
13
|
ref $_ |
220
|
|
|
|
|
|
|
? ref $_ eq 'HASH' |
221
|
|
|
|
|
|
|
? $type->new($_) |
222
|
|
|
|
|
|
|
: ref $_ eq $type |
223
|
|
|
|
|
|
|
? $_ |
224
|
|
|
|
|
|
|
: croak "cannot use " . ref($_) . " reference as value for $name - $type required" |
225
|
|
|
|
|
|
|
: $type->new({ value => $_ }) |
226
|
30
|
50
|
66
|
|
|
241
|
} @{ $_[1] } |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
227
|
|
|
|
|
|
|
] |
228
|
|
|
|
|
|
|
: $is_ref eq 'HASH' |
229
|
|
|
|
|
|
|
? $type->new( $_[1] ) |
230
|
|
|
|
|
|
|
# neither ARRAY nor HASH - probably an object... - |
231
|
|
|
|
|
|
|
# do we need to test for it being blessed? |
232
|
|
|
|
|
|
|
: blessed $_[1] && $_[1]->isa($type) # of required type ? |
233
|
|
|
|
|
|
|
? $_[1] # use it |
234
|
|
|
|
|
|
|
: die croak "cannot use $is_ref reference as value for $name - $type required" |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# not $is_ref |
237
|
|
|
|
|
|
|
: defined $_[1] ? $type->new({ value => $_[1] }) : () ; |
238
|
28
|
|
|
|
|
63
|
return; |
239
|
63
|
|
|
|
|
246
|
}; |
240
|
|
|
|
|
|
|
|
241
|
63
|
|
|
|
|
221
|
*{ "$class\::add_$method_name" } = sub { |
242
|
12
|
100
|
|
12
|
|
436
|
warn "attempting to add empty value to " . ref $_[0] |
243
|
|
|
|
|
|
|
if not defined $_[1]; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# first call |
246
|
|
|
|
|
|
|
# test for existance, not for definedness |
247
|
12
|
100
|
|
|
|
54
|
if (not exists $attribute_ref->{ ${ $_[0]} }) { |
|
12
|
|
|
|
|
110
|
|
248
|
2
|
|
|
|
|
4
|
$attribute_ref->{ ${ $_[0]} } = $_[1]; |
|
2
|
|
|
|
|
4
|
|
249
|
2
|
|
|
|
|
5
|
return; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
10
|
100
|
|
|
|
10
|
if (not ref $attribute_ref->{ ${ $_[0]} } eq 'ARRAY') { |
|
10
|
|
|
|
|
24
|
|
253
|
|
|
|
|
|
|
# second call: listify previous value if it's no list and add current |
254
|
2
|
|
|
|
|
2
|
$attribute_ref->{ ${ $_[0]} } = [ $attribute_ref->{ ${ $_[0]} }, $_[1] ]; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
4
|
|
255
|
2
|
|
|
|
|
3
|
return; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# second and following: add to list |
259
|
8
|
|
|
|
|
9
|
push @{ $attribute_ref->{ ${ $_[0]} } }, $_[1]; |
|
8
|
|
|
|
|
5
|
|
|
8
|
|
|
|
|
19
|
|
260
|
8
|
|
|
|
|
10
|
return; |
261
|
63
|
|
|
|
|
137
|
}; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
# TODO Could be moved as normal method into base class, e.g. here. |
265
|
|
|
|
|
|
|
# Hmm. let's see... |
266
|
30
|
|
|
|
|
88
|
*{ "$class\::new" } = sub { |
267
|
|
|
|
|
|
|
# We're working on @_ for speed. |
268
|
|
|
|
|
|
|
# Normally, the first line would look like this: |
269
|
|
|
|
|
|
|
# my ($class, $args_of) = @_; |
270
|
|
|
|
|
|
|
# |
271
|
|
|
|
|
|
|
# The hanging side comment show you what would be there, then. |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# Read as: |
274
|
|
|
|
|
|
|
# my $self = bless \(my $o = Class::Std::Fast::ID()), $class; |
275
|
34
|
|
|
34
|
|
10377
|
my $self = bless \(my $o = Class::Std::Fast::ID()), $_[0]; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# Set attributes if passed via { xmlattr => \%attributes } |
278
|
|
|
|
|
|
|
# |
279
|
|
|
|
|
|
|
# This works just because |
280
|
|
|
|
|
|
|
# a) xmlattr cannot be used as valid XML identifier (it starts |
281
|
|
|
|
|
|
|
# with "xml" which is banned by the XML schema standard) |
282
|
|
|
|
|
|
|
# b) $o->attr($attribute_ref) passes $attribute_ref to the |
283
|
|
|
|
|
|
|
# attribute object's constructor |
284
|
|
|
|
|
|
|
# c) we are in the object's constructor here (which means that) |
285
|
|
|
|
|
|
|
# no attributes object can have been legally constructed |
286
|
|
|
|
|
|
|
# before. |
287
|
34
|
100
|
|
|
|
186
|
if (exists $_[1]->{xmlattr}) { # $args_of->{xmlattr} |
288
|
1
|
|
|
|
|
5
|
$self->attr(delete $_[1]->{xmlattr}); |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# iterate over keys of arguments |
292
|
|
|
|
|
|
|
# and call set appropriate field in clase |
293
|
34
|
|
|
|
|
80
|
map { ($ATTRIBUTES_OF{ $class }->{ $_ }) |
294
|
|
|
|
|
|
|
? do { |
295
|
28
|
|
|
|
|
44
|
my $method = "set_$_"; |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# keep in sync with Generator::Template::Plugin::XSD - maybe use |
298
|
|
|
|
|
|
|
# function to allow substituting via symbol table... |
299
|
28
|
|
|
|
|
48
|
$method =~s{[\.\-]}{_}xmsg; |
300
|
|
|
|
|
|
|
|
301
|
28
|
|
|
|
|
243
|
$self->$method( $_[1]->{ $_ } ); # ( $args_of->{ $_ } ); |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
: $_ =~ m{ \A # beginning of string |
304
|
|
|
|
|
|
|
xmlns # xmlns |
305
|
|
|
|
|
|
|
}xms # get_elements is inlined for performance. |
306
|
|
|
|
|
|
|
? () |
307
|
31
|
100
|
|
|
|
89
|
: do { |
|
|
100
|
|
|
|
|
|
308
|
2
|
|
|
|
|
11
|
croak "unknown field $_ in $class. Valid fields are:\n" |
309
|
2
|
|
|
|
|
5
|
. join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n" |
310
|
|
|
|
|
|
|
. "Structure given:\n" . Dumper @_ }; |
311
|
34
|
|
|
|
|
34
|
} keys %{ $_[1] }; # %$args_of; |
312
|
30
|
|
|
|
|
64
|
return $self; |
313
|
30
|
|
|
|
|
117
|
}; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# this _serialize method works fine for and |
316
|
|
|
|
|
|
|
# complextypes, as well as for or |
317
|
|
|
|
|
|
|
# , and attribute sets. |
318
|
|
|
|
|
|
|
# |
319
|
|
|
|
|
|
|
# But what about choice, extension ? |
320
|
|
|
|
|
|
|
# |
321
|
|
|
|
|
|
|
# Triggers XML attribute serialization if the options hash ref contains |
322
|
|
|
|
|
|
|
# a attr element with a true value. |
323
|
30
|
|
|
|
|
84
|
*{ "$class\::_serialize" } = sub { |
324
|
27
|
|
|
27
|
|
26
|
my $ident = ${ $_[0] }; |
|
27
|
|
|
|
|
218
|
|
325
|
27
|
|
|
|
|
35
|
my $option_ref = $_[1]; |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# return concatenated return value of serialize call of all |
328
|
|
|
|
|
|
|
# elements retrieved from get_elements expanding list refs. |
329
|
33
|
|
|
|
|
57
|
return \join q{} , map { |
330
|
27
|
|
|
|
|
54
|
my $element = $ATTRIBUTES_OF{ $class }->{ $_ }->{ $ident }; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# do we have some content |
333
|
33
|
100
|
|
|
|
59
|
if (defined $element) { |
334
|
29
|
100
|
|
|
|
78
|
$element = [ $element ] if not ref $element eq 'ARRAY'; |
335
|
|
|
|
|
|
|
# use || $_; for backward compatibility |
336
|
29
|
|
66
|
|
|
71
|
my $name = $NAMES_OF{$class}->{$_} || $_; |
337
|
29
|
|
|
|
|
56
|
my $target_namespace = $_[0]->get_xmlns(); |
338
|
|
|
|
|
|
|
map { |
339
|
|
|
|
|
|
|
# serialize element elements with their own serializer |
340
|
|
|
|
|
|
|
# but name them like they're named here. |
341
|
|
|
|
|
|
|
# TODO: check. element ref="" has a name??? |
342
|
51
|
100
|
|
|
|
191
|
if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) { |
|
29
|
|
|
|
|
32
|
|
343
|
|
|
|
|
|
|
# serialize elements of different namespaces |
344
|
|
|
|
|
|
|
# with namespace declaration |
345
|
13
|
100
|
|
|
|
32
|
($target_namespace ne $_->get_xmlns()) |
346
|
|
|
|
|
|
|
? $_->serialize({ name => $name, qualified => 1 }) |
347
|
|
|
|
|
|
|
: $_->serialize({ name => $name }); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
# serialize complextype elments (of other types) with their |
350
|
|
|
|
|
|
|
# serializer, but add element tags around. |
351
|
|
|
|
|
|
|
else { |
352
|
|
|
|
|
|
|
# default for undef is true |
353
|
38
|
50
|
33
|
|
|
83
|
if (! defined $ELEMENT_FORM_QUALIFIED_OF{ $class } |
354
|
|
|
|
|
|
|
or $ELEMENT_FORM_QUALIFIED_OF{ $class } |
355
|
|
|
|
|
|
|
) { |
356
|
|
|
|
|
|
|
# handle types from different namespaces |
357
|
|
|
|
|
|
|
# |
358
|
|
|
|
|
|
|
# serialize with last namespace put on stack |
359
|
|
|
|
|
|
|
# if the last namespace is a change from the |
360
|
|
|
|
|
|
|
# before-last |
361
|
|
|
|
|
|
|
# |
362
|
38
|
50
|
66
|
|
|
71
|
if ( |
|
|
|
33
|
|
|
|
|
363
|
|
|
|
|
|
|
exists $option_ref->{ xmlns_stack } |
364
|
34
|
|
|
|
|
104
|
&& (scalar @{ $option_ref->{ xmlns_stack } } >= 2) |
365
|
|
|
|
|
|
|
&& ($option_ref->{ xmlns_stack }->[-1] ne $option_ref->{ xmlns_stack }->[-2])) { |
366
|
|
|
|
|
|
|
# warn "New namespace: ", $option_ref->{ xmlns_stack }->[-1]; |
367
|
|
|
|
|
|
|
join q{}, $_->start_tag({ name => $name , |
368
|
0
|
|
|
|
|
0
|
xmlns => $option_ref->{ xmlns_stack }->[-1], |
369
|
0
|
|
|
|
|
0
|
%{ $option_ref } }) |
370
|
|
|
|
|
|
|
, $_->serialize($option_ref) |
371
|
0
|
|
|
|
|
0
|
, $_->end_tag({ name => $name , %{ $option_ref } }); |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
else { |
374
|
38
|
|
|
|
|
139
|
join q{}, $_->start_tag({ name => $name , %{ $option_ref } }) |
|
38
|
|
|
|
|
87
|
|
375
|
|
|
|
|
|
|
, $_->serialize($option_ref) |
376
|
38
|
|
|
|
|
36
|
, $_->end_tag({ name => $name , %{ $option_ref } }); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
else { |
380
|
|
|
|
|
|
|
# in elementFormDefault="unqualified" mode, |
381
|
|
|
|
|
|
|
# the serialize method has to set |
382
|
|
|
|
|
|
|
# xmnlns="" on all elements inside a ComplexType |
383
|
|
|
|
|
|
|
# |
384
|
|
|
|
|
|
|
# Other serializers usually use prefixes |
385
|
|
|
|
|
|
|
# for "unqualified" and just omit all prefixes |
386
|
|
|
|
|
|
|
# for inner elements |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# check whether we "had" a xmlns around |
389
|
0
|
|
|
|
|
0
|
my $set_xmlns = delete $option_ref->{xmlns}; |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
# serialize start tag with xmlns="" if out parent |
392
|
|
|
|
|
|
|
# did not do that |
393
|
0
|
|
|
|
|
0
|
join q{}, $_->start_tag({ |
394
|
|
|
|
|
|
|
name => $name, |
395
|
0
|
|
|
|
|
0
|
%{ $option_ref }, |
396
|
|
|
|
|
|
|
(! defined $set_xmlns) |
397
|
|
|
|
|
|
|
? (xmlns => "") |
398
|
|
|
|
|
|
|
: () |
399
|
|
|
|
|
|
|
}) |
400
|
|
|
|
|
|
|
# add xmlns = "" to child serialize options |
401
|
|
|
|
|
|
|
# to avoid putting xmlns="" everywhere |
402
|
0
|
|
|
|
|
0
|
, $_->serialize({ %{$option_ref}, xmlns => "" }) |
403
|
0
|
0
|
|
|
|
0
|
, $_->end_tag({ name => $name , %{ $option_ref } }); |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
} |
406
|
29
|
|
|
|
|
28
|
} @{ $element } |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
else { |
409
|
4
|
|
|
|
|
10
|
q{}; |
410
|
|
|
|
|
|
|
} |
411
|
27
|
|
|
|
|
33
|
} (@{ $ELEMENTS_FROM{ $class } }); |
412
|
30
|
|
|
|
|
130
|
}; |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# put hidden complex serializer into class |
415
|
|
|
|
|
|
|
# ... but not for AttributeSet classes |
416
|
30
|
100
|
|
|
|
256
|
if ( ! $class->isa('SOAP::WSDL::XSD::Typelib::AttributeSet')) { |
417
|
25
|
|
|
|
|
131
|
*{ "$class\::serialize" } = \&__serialize_complex; |
|
25
|
|
|
|
|
109
|
|
418
|
|
|
|
|
|
|
}; |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub _set_element_form_qualified { |
422
|
0
|
|
|
0
|
|
0
|
$ELEMENT_FORM_QUALIFIED_OF{ $_[0] } = $_[1]; |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
# Just as fallback: return no attribute set class as default. |
426
|
|
|
|
|
|
|
# Subclasses may override |
427
|
1
|
|
|
1
|
|
6
|
sub __get_attr_class {}; |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
# hidden complex serializer |
430
|
|
|
|
|
|
|
sub __serialize_complex { |
431
|
|
|
|
|
|
|
# we work on @_ for performance. |
432
|
23
|
|
100
|
23
|
|
1619
|
$_[1] ||= {}; # $option_ref |
433
|
|
|
|
|
|
|
|
434
|
23
|
|
|
|
|
22
|
push @{ $_[1]->{ xmlns_stack } }, $_[0]->get_xmlns(); |
|
23
|
|
|
|
|
99
|
|
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# get content first (pass by reference to avoid copying) |
437
|
23
|
|
|
|
|
66
|
my $content_ref = $_[0]->_serialize($_[1]); # option_ref |
438
|
|
|
|
|
|
|
|
439
|
23
|
|
|
|
|
25
|
pop @{ $_[1]->{ xmlns_stack } }; |
|
23
|
|
|
|
|
39
|
|
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
# do we have a empty element ? |
442
|
6
|
|
|
|
|
31
|
return $_[0]->start_tag({ %{ $_[1] }, empty => 1 }) |
|
23
|
|
|
|
|
54
|
|
443
|
23
|
100
|
|
|
|
20
|
if not length ${ $content_ref }; |
444
|
|
|
|
|
|
|
|
445
|
17
|
|
|
|
|
67
|
return join q{}, $_[0]->start_tag($_[1]), ${ $content_ref }, $_[0]->end_tag(); |
|
17
|
|
|
|
|
53
|
|
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub get_xmlns { |
449
|
35
|
|
|
35
|
0
|
557
|
return q{} |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
1; |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
__END__ |