no
warnings
qw(redefine)
;
no
strict
qw(refs)
;
$SIG
{__WARN__} =
sub
{
warn
@_
unless
$_
[0] =~ /Tie::Hash::FIELDS|Cache::RemovalStrategy|XPath\/
Node\/Element|XMLSchemaSOAP1_2::as_dateTime/;
};
sub
serialize_attr {
my
(
$self
,
$args
) =
@_
;
my
$result
=
q{}
;
if
(
$xml_attr_of
{${
$_
[0]}}) {
$result
=
$xml_attr_of
{${
$_
[0]}}->serialize();
}
if
(
$args
->{xsitype}) {
$result
=
$result
.
" xsi:type=\"$args->{xsitype}\" "
;
}
if
(
$args
->{xsitypens}) {
$result
=
$result
.
" xmlns:$args->{xsitypens}->{name}=\""
.
"$args->{xsitypens}->{value}\" "
;
}
return
$result
;
}
sub
_factory {
my
$class
=
shift
;
$ELEMENTS_FROM
->{
$class
} =
shift
;
$ATTRIBUTES_OF
->{
$class
} =
shift
;
$CLASSES_OF
->{
$class
} =
shift
;
$NAMES_OF
->{
$class
} =
shift
;
while
(
my
(
$name
,
$attribute_ref
) =
each
%{
$ATTRIBUTES_OF
->{
$class
}}) {
my
$type
=
$CLASSES_OF
->{
$class
}->{
$name
}
or croak
"No class given for $name"
;
Class::Load::is_class_loaded(
$type
)
or
eval
{ Class::Load::load_class
$type
} or croak $@;
my
$is_list
=
$type
->isa(
'SOAP::WSDL::XSD::Typelib::Builtin::list'
);
my
$method_name
=
$name
;
$method_name
=~ s{[\.\-]}{_}xmsg;
*{
"$class\::set_$method_name"
} =
sub
{
if
(not
$#_
) {
delete
$attribute_ref
->{${
$_
[0]}};
return
;
}
my
$is_ref
=
ref
$_
[1];
$attribute_ref
->{${
$_
[0]}} =
(
$is_ref
)
? (
$is_ref
eq
'ARRAY'
)
?
$is_list
?
$type
->new({
value
=>
$_
[1]})
: [
map
{
ref
$_
?
ref
$_
eq
'HASH'
?
_hash_to_object(
$type
,
$_
)
:
$_
->isa(
$type
)
?
$_
: croak
"cannot use "
.
ref
(
$_
) .
" reference as value for"
.
" $name - $type required"
:
$type
->new({
value
=>
$_
})
} @{
$_
[1]}]
:
$is_ref
eq
'HASH'
?
do
{
_hash_to_object(
$type
,
$_
[1]);
}
:
blessed
$_
[1] &&
$_
[1]->isa(
$type
)
?
$_
[1]
:
die
croak
"cannot use $is_ref reference as value for "
.
"$name - $type required"
:
defined
$_
[1] ?
$type
->new({
value
=>
$_
[1]})
: ();
return
;
};
*{
"$class\::add_$method_name"
} =
sub
{
warn
"attempting to add empty value to "
.
ref
$_
[0]
if
not
defined
$_
[1];
if
(not
exists
$attribute_ref
->{${
$_
[0]}}) {
$attribute_ref
->{${
$_
[0]}} =
$_
[1];
return
;
}
if
(not
ref
$attribute_ref
->{${
$_
[0]}} eq
'ARRAY'
) {
$attribute_ref
->{${
$_
[0]}} = [
$attribute_ref
->{${
$_
[0]}},
$_
[1]];
return
;
}
push
@{
$attribute_ref
->{${
$_
[0]}}},
$_
[1];
return
;
};
}
*{
"$class\::new"
} =
sub
{
my
$self
=
bless
\(
my
$o
= Class::Std::Fast::ID()),
$_
[0];
if
(
exists
$_
[1]->{xmlattr}) {
$self
->attr(
delete
$_
[1]->{xmlattr});
}
map
{
(
$ATTRIBUTES_OF
->{
$class
}->{
$_
})
?
do
{
my
$method
=
"set_$_"
;
$method
=~ s{[\.\-]}{_}xmsg;
$self
->
$method
(
$_
[1]->{
$_
});
}
:
$_
=~ m{ \A
xmlns|xsi_type
}xms
? ()
:
do
{
croak
"Unknown field $_ in $class.\nValid fields are:\n"
.
join
(
', '
, @{
$ELEMENTS_FROM
->{
$class
}}) .
"\n"
.
"Structure given:\n"
. Dumper(
$_
[1]);
};
}
keys
%{
$_
[1]};
return
$self
;
};
*{
"$class\::_serialize"
} =
sub
{
my
$ident
= ${
$_
[0]};
my
$option_ref
=
$_
[1];
return
\
join
q{}
,
map
{
my
$element
=
$ATTRIBUTES_OF
->{
$class
}->{
$_
}->{
$ident
};
if
(
defined
$element
) {
$element
= [
$element
]
if
not
ref
$element
eq
'ARRAY'
;
my
$name
=
$NAMES_OF
->{
$class
}->{
$_
} ||
$_
;
my
$target_namespace
=
$_
[0]->get_xmlns();
map
{
if
(
$_
->isa(
'SOAP::WSDL::XSD::Typelib::Element'
))
{
(
$target_namespace
ne
$_
->get_xmlns())
?
$_
->serialize({
name
=>
$name
,
qualified
=> 1})
:
$_
->serialize({
name
=>
$name
});
}
else
{
if
(!
defined
$ELEMENT_FORM_QUALIFIED_OF
->{
$class
}
or
$ELEMENT_FORM_QUALIFIED_OF
->{
$class
})
{
if
(
exists
$option_ref
->{xmlns_stack}
&& (
scalar
@{
$option_ref
->{xmlns_stack}} >= 2)
&& (
$option_ref
->{xmlns_stack}->[-1] ne
$option_ref
->{xmlns_stack}->[-2]))
{
join
q{}
,
$_
->start_tag({
name
=>
$name
,
xmlns
=>
$option_ref
->{xmlns_stack}->[-1],
%{
$option_ref
}}
),
$_
->serialize(
$option_ref
),
$_
->end_tag({
name
=>
$name
, %{
$option_ref
}});
}
else
{
my
$refname
=
ref
(
$_
);
my
$classname
=
$CLASSES_OF
->{
$class
}->{
$name
};
if
(
$classname
&&
$classname
ne
ref
(
$_
)) {
my
$xsitypens
= {};
if
(
$option_ref
->{xmlns_stack}->[-1] ne
$_
->get_xmlns()) {
$xsitypens
->{name} =
"xns"
;
$xsitypens
->{value} =
$_
->get_xmlns();
$option_ref
->{xsitypens} =
$xsitypens
;
}
my
$package_name
=
ref
(
$_
);
$package_name
=~ /^.*::(.*)$/;
my
$xsi_type
= $1;
$option_ref
->{xsitype} =
(
$xsitypens
->{name} ?
$xsitypens
->{name} .
":"
:
""
) .
"$xsi_type"
;
}
else
{
delete
$option_ref
->{xsitype};
}
my
$class_isa
=
$class
.
"::ISA"
;
my
@class_parents
=
@$class_isa
;
my
$requires_namespace
= 0;
foreach
my
$parent
(
@class_parents
) {
my
%parent_elements
=
map
{
$_
=> 1 } @{
$ELEMENTS_FROM
->{
$parent
}};
my
$parent_has_element
=
exists
(
$parent_elements
{
$name
});
if
(
$parent_has_element
) {
my
$parent_xns
;
eval
"\$parent_xns = "
.
$parent
.
"::get_xmlns()"
;
if
(
$parent_xns
ne
$option_ref
->{xmlns_stack}->[-1]) {
$requires_namespace
= 1;
}
}
}
if
(
$requires_namespace
) {
join
q{}
,
$_
->start_tag({
name
=>
$name
,
xmlns
=>
$_
->get_xmlns(),
%{
$option_ref
}}
),
$_
->serialize(
$option_ref
),
$_
->end_tag({
name
=>
$name
, %{
$option_ref
}});
}
else
{
join
q{}
,
$_
->start_tag({
name
=>
$name
, %{
$option_ref
}}),
$_
->serialize(
$option_ref
),
$_
->end_tag({
name
=>
$name
, %{
$option_ref
}});
}
}
}
else
{
my
$set_xmlns
=
delete
$option_ref
->{xmlns};
join
q{}
,
$_
->start_tag({
name
=>
$name
,
%{
$option_ref
},
(!
defined
$set_xmlns
) ? (
xmlns
=>
""
) : ()}
),
$_
->serialize({%{
$option_ref
},
xmlns
=>
""
}),
$_
->end_tag({
name
=>
$name
, %{
$option_ref
}});
}
}
} @{
$element
};
}
else
{
q{}
;
}
} (@{
$ELEMENTS_FROM
->{
$class
}});
};
if
(!
$class
->isa(
'SOAP::WSDL::XSD::Typelib::AttributeSet'
)) {
*{
"$class\::serialize"
} =
\
&SOAP::WSDL::XSD::Typelib::ComplexType::__serialize_complex
;
}
}
sub
_hash_to_object {
my
(
$type
,
$hash
) =
@_
;
if
(
$hash
->{
"xsi_type"
}) {
my
$base_type
=
$type
;
my
$xsi_type
=
$hash
->{
"xsi_type"
};
$type
=
substr
(
$type
, 0,
rindex
(
$type
,
"::"
) + 2) .
$xsi_type
;
eval
(
"require $type"
);
die
croak
"xsi_type $xsi_type not found"
if
$@;
my
$instance
=
$type
->new(
$hash
);
die
croak
"xsi_type $xsi_type must inherit from "
.
"$type"
if
not
$instance
->isa(
$base_type
);
return
$instance
;
}
else
{
return
$type
->new(
$hash
);
}
}
sub
as_hash_ref {
my
$self
=
$_
[0];
my
$attributes_ref
=
$self
->__get_object_attributes(
$self
);
my
$hash_of_ref
= {};
if
(
$_
[0]->isa(
'SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType'
)) {
$hash_of_ref
->{value} =
$_
[0]->get_value();
}
else
{
foreach
my
$attribute
(
keys
%{
$attributes_ref
}) {
next
if
not
defined
$attributes_ref
->{
$attribute
}->{${
$_
[0]}};
my
$value
=
$attributes_ref
->{
$attribute
}->{${
$_
[0]}};
$attribute
=~ s/__/./g;
$hash_of_ref
->{
$attribute
} =
blessed
$value
?
$value
->isa(
'SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType'
)
?
$value
->get_value()
:
$value
:
ref
$value
eq
'ARRAY'
? [
map
{
$_
->isa(
'SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType'
)
?
$_
->get_value()
:
$_
} @{
$value
}]
:
die
"Neither blessed obj nor list ref"
;
}
}
no
warnings
"once"
;
return
$hash_of_ref
if
$_
[1] or
$AS_HASH_REF_WITHOUT_ATTRIBUTES
;
if
(
exists
$xml_attr_of
{${
$_
[0]}}) {
$hash_of_ref
->{xmlattr} =
$xml_attr_of
{${
$_
[0]}}->as_hash_ref();
}
return
$hash_of_ref
;
}
sub
__get_object_attributes {
my
$self
=
shift
;
my
$object
=
shift
;
my
@types
= (
ref
$object
);
my
%attributes
;
while
(
my
$type
=
pop
(
@types
)) {
eval
(
"require $type"
);
my
$type_bases_name
=
$type
.
"::ISA"
;
push
@types
,
@$type_bases_name
;
my
$attributes_ref
=
$ATTRIBUTES_OF
->{
$type
};
for
my
$key
(
keys
%$attributes_ref
) {
my
$value
=
$attributes_ref
->{
$key
};
if
(not
exists
$attributes
{
$key
}) {
$attributes
{
$key
} =
$value
;
}
}
}
return
\
%attributes
;
}
sub
__get_object_names {
my
$object
=
$_
[1];
my
@types
= (
ref
$object
);
my
%names
;
while
(
my
$type
=
pop
(
@types
)) {
eval
(
"require $type"
);
my
$type_bases_name
=
$type
.
"::ISA"
;
push
@types
,
@$type_bases_name
;
my
$names_ref
=
$NAMES_OF
{
$type
};
for
my
$key
(
keys
%$names_ref
) {
my
$value
=
$names_ref
->{
$key
};
if
(not
exists
$names
{
$key
}) {
$names
{
$key
} =
$value
;
}
}
}
return
\
%names
;
}
sub
find {
my
(
$self
,
$xpath_expr
) =
@_
;
my
$parser_node
=
Google::Ads::Common::XPathSAXParser::get_node_from_object(
$self
);
my
@return_list
= ();
if
(
defined
$parser_node
) {
my
$node_set
=
$parser_node
->find(
$xpath_expr
);
foreach
my
$node
(
$node_set
->get_nodelist()) {
my
$soap_object
=
Google::Ads::Common::XPathSAXParser::get_object_from_node(
$node
);
if
(
defined
$soap_object
) {
push
@return_list
,
$soap_object
;
}
}
}
return
\
@return_list
;
}
no
warnings
"once"
;
*Google::Ads::SOAP::ComplexType::valueof
=
\
&Google::Ads::SOAP::ComplexType::find
;
'%{}'
=>
'as_hash_ref'
,
fallback
=> 1,
);