import SOAP-WSDL 2.00_09 from CPAN

git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_09
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_09.tar.gz
This commit is contained in:
Martin Kutter
2009-12-12 19:47:47 -08:00
committed by Michael G. Schwern
parent 312f3d6bbd
commit a554e87f49
29 changed files with 1041 additions and 399 deletions
+20 -10
View File
@@ -192,17 +192,17 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
[% END %]
__PACKAGE__->_factory(
[ qw([% FOREACH element=self.get_element -%]
[% element.get_name %]
[ qw([% FOREACH element=self.get_element -%]
[% element.get_name %]
[% END %]) ],
{
[% FOREACH element=self.get_element %][% element.get_name %] => \%[% element.get_name %]_of,
[% END %]
{
[% FOREACH element=self.get_element %][% element.get_name %] => \%[% element.get_name %]_of,
[% END %]
},
{
[%-
[%-
FOREACH element=self.get_element;
IF (element.get_type);
IF (element.get_type); # element type="..."
split_name = element.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
@@ -210,8 +210,13 @@ __PACKAGE__->_factory(
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
ELSIF (simpleType = element.first_simpleType);
[%- END;
ELSIF (element.get_ref); # element ref="..."
split_name = element.get_ref.split(':');
prefix = split_name.0;
localname = split_name.1; %]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[% ELSIF (simpleType = element.first_simpleType);
base = simpleType.get_base();
%]
# basic simple type handling: we treat atomic simple types
@@ -269,7 +274,12 @@ methods:
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
ELSIF (simpleType = element.first_simpleType);
ELSIF (element.get_ref); # element ref="..."
split_name = element.get_ref.split(':');
prefix = split_name.0;
localname = split_name.1; %]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[% ELSIF (simpleType = element.first_simpleType);
base = simpleType.get_base();
split_name = base.split(':');
prefix = split_name.0;
+24 -10
View File
@@ -90,8 +90,8 @@ sub serialize {
elsif (my $ref_name = $ref_of{ $ident }) { # ref
my ($prefix, $localname) = split /:/ , $ref_name;
my $ns = $ns_map{ $prefix };
$type = $typelib->find_type( $ns, $localname );
die "no type for $prefix:$localname" if (not $type);
$type = $typelib->find_element( $ns, $localname );
die "no element for ref $prefix:$localname" if (not $type);
return $type->serialize( $name, $value, $opt );
}
@@ -130,6 +130,12 @@ sub explain {
}
return $type->explain( $opt, $self->get_name() );
}
elsif (my $element_name = $self->get_ref() ) {
my $element = $opt->{ wsdl }->first_types()->find_element(
$opt->{ wsdl }->_expand( $element_name )
);
return $element->explain( $opt, $self->get_name() );
}
# return if it's not a derived type - we don't handle
# other stuff yet.
@@ -152,7 +158,7 @@ sub explain {
delete $opt->{ anonymous };
return $text .= $type->explain( $opt, undef );
}
return $text .= $type->explain( $opt, $self->get_name() );
return $text .= $type->explain( $opt, $name || $self->get_name() );
return 'ERROR: '. $@;
}
@@ -240,6 +246,7 @@ package [% element_prefix %][% self.get_name %];
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
[% IF (type = self.first_simpleType) %]
# <element name="[% self.get_name %]"><simpleType> definition
use SOAP::WSDL::XSD::Typelib::SimpleType;
@@ -249,6 +256,17 @@ use base qw(
[% type.flavor_class %]
[% type.base_class($type_prefix) %]
);
[% ELSIF (ref_name = self.get_ref);
split_name = ref_name.split(':');
prefix = split_name.0;
localname = split_name.1;
ref_class = element_prefix _ localname;
%]
# <element name="[% self.get_name %]" ref="[% ref_name %]"> definition
# use [% ref_class %];
use base qw(
[% ref_class %]
);
[% ELSIF (type = self.first_complexType) %]
# atomic complexType
# <element name="[% self.get_name %]"><complexType> definition
@@ -263,7 +281,7 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
[% END %]
__PACKAGE__->_factory(
[ qw([% FOREACH element = type.get_element %]
[ qw([% FOREACH element = type.get_element %]
[% element.get_name %]
[% END %]) ],
{
@@ -276,10 +294,10 @@ __PACKAGE__->_factory(
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' %]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE %]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[% END %]
[% END %]
[% END %]
}
);
@@ -304,10 +322,6 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
[% base_class %]
);
[% ELSIF (element = self.get_ref)
%]
# element ref"element" definition
# Sorry, we don't handle this yet...
[% END %]
sub get_xmlns { '[% self.get_targetNamespace %]' }
+1
View File
@@ -7,6 +7,7 @@ use base qw(SOAP::WSDL::Base);
# child elements
my %type_of :ATTR(:name<type> :default<[]>);
my %element_of :ATTR(:name<element> :default<[]>);
my %group_of :ATTR(:name<group> :default<[]>);
# attributes
my %attributeFormDefault_of :ATTR(:name<attributeFormDefault> :default<()>);
@@ -29,6 +29,13 @@ sub as_bool :BOOLIFY {
return $value_of { ident $_[0] };
}
sub _get_handlers {
my $parser = $_[1];
return {
Char => $parser->characters(),
}
}
Class::Std::initialize(); # make :BOOLIFY overloading serializable
+1 -1
View File
@@ -40,7 +40,7 @@ sub serialize {
, $self->end_tag($opt);
}
sub as_num :NUMERIFY {
sub as_num :NUMERIFY :BOOLIFY {
return $_[0]->get_value();
}
+2 -2
View File
@@ -36,10 +36,10 @@ BEGIN {
sub set_value {
# use set_value from base class if we have a XML-DateTime format
#2037-12-31T00:00:00.0000000+01:00
#2037-12-31+01:00
if (
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
(:? [\+\-] \d{2} \: \d{2} )?
(:? [\+\-] \d{2} \: \d{2} )?$
}xms
) {
$_[0]->SUPER::set_value($_[1])
@@ -46,16 +46,19 @@ sub set_value {
$_[0]->SUPER::set_value($_[1])
}
# use a combination of strptime and strftime for converting the date
# strptime does not emit timezone info, so we're pretty fucked up here.
#
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
# whants it as [+-]00:00
# We leave out the optional nanoseconds part, as it would always be empty.
else {
# strptime sets empty values to undef - and strftime doesn't like that...
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
undef $time_from[-1];
my $time_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from );
substr $time_str, -2, 0, ':';
$_[0]->SUPER::set_value($time_str);
}
}
@@ -22,26 +22,3 @@ BEGIN {
};
}
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong - unsigned long integer objects
=head1 DESCRIPTION
Subclass of nonNegativeInteger.
=head1 LICENSE
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut
+138 -66
View File
@@ -40,15 +40,13 @@ sub _factory {
*{ "$class\::set_$name" } = sub {
my ($self, $value) = @_;
=pod
=for developers
The structure below looks rather weird, but is optimized for performance.
We could use sub calls for sure, but these are much slower. And the logic
is not that easy:
we accept:
a) objects
b) scalars
@@ -92,7 +90,7 @@ is not that easy:
? $type->new( $value )
: $is_ref eq $type
? $value
: die 'Cannot use non-ARRAY/HASH as data'
: die croak "cannot use $is_ref reference as value for $name - $type required"
: $type->new({ value => $value });
};
@@ -114,70 +112,69 @@ is not that easy:
return push @{ $attribute_ref->{ $ident } }, $value;
};
*{ "$class\::START" } = sub {
my ($self, $ident, $args_of) = @_;
# iterate over keys of arguments
# and call set appropriate field in clase
map { ($ATTRIBUTES_OF{ $class }->{ $_ })
? do {
my $method = "set_$_";
$self->$method( $args_of->{ $_ } );
}
: $_ =~ m{ \A # beginning of string
xmlns # xmlns
}xms
? do {}
: do { use Data::Dumper;
croak "unknown field $_ in $class. Valid fields are "
. join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n"
. Dumper @_ };
# TODO maybe only warn for unknown fields ?
} keys %$args_of;
};
# this serialize method works fine for <all> and <sequence>
# complextypes, as well as for <restriction><all> or
# <restriction><sequence>.
# But what about choice, group, extension ?
#
}
*{ "$class\::START" } = sub {
my ($self, $ident, $args_of) = @_;
# iterate over keys of arguments
# and call set appropriate field in clase
map { ($ATTRIBUTES_OF{ $class }->{ $_ })
? do {
my $method = "set_$_";
$self->$method( $args_of->{ $_ } );
}
: $_ =~ m{ \A # beginning of string
xmlns # xmlns
}xms
? do {}
: do { use Data::Dumper;
croak "unknown field $_ in $class. Valid fields are:\n"
. join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n"
. "Structure given:\n" . Dumper @_ };
} keys %$args_of;
return $self;
};
# this serialize method works fine for <all> and <sequence>
# complextypes, as well as for <restriction><all> or
# <restriction><sequence>.
# But what about choice, group, extension ?
*{ "$class\::_serialize" } = sub {
my $ident = ident $_[0];
# my $class = ref $_[0];
# return concatenated return value of serialize call of all
# elements retrieved from get_elements expanding list refs.
# get_elements is inlined for performance.
return join q{} , map {
my $element = $ATTRIBUTES_OF{ $class }->{ $_ }->{ $ident };
if (defined $element) {
$element = [ $element ]
if not ref $element eq 'ARRAY';
my $name = $_;
my $ident = ident $_[0];
# my $class = ref $_[0];
# return concatenated return value of serialize call of all
# elements retrieved from get_elements expanding list refs.
# get_elements is inlined for performance.
return join q{} , map {
my $element = $ATTRIBUTES_OF{ $class }->{ $_ }->{ $ident };
# do we have some content
if (defined $element) {
$element = [ $element ]
if not ref $element eq 'ARRAY';
my $name = $_;
map {
# serialize element elements with their own serializer
# but name them like they're named here.
if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) {
$_->serialize( { name => $name } );
}
# serialize complextype elments (of other types) with their
# serializer, but add element tags around.
else {
join q{}, $_->start_tag({ name => $name })
, $_->serialize()
, $_->end_tag({ name => $name });
}
} @{ $element }
}
else {
q{};
}
} (@{ $ELEMENTS_FROM{ $class } });
};
map {
# serialize element elements with their own serializer
# but name them like they're named here.
if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) {
$_->serialize( { name => $name } );
}
# serialize complextype elments (of other types) with their
# serializer, but add element tags around.
else {
join q{}, $_->start_tag({ name => $name })
, $_->serialize()
, $_->end_tag({ name => $name });
}
} @{ $element }
}
else {
q{};
}
} (@{ $ELEMENTS_FROM{ $class } });
};
*{ "$class\::serialize" } = sub {
my ($self, $opt) = @_;
@@ -191,7 +188,7 @@ is not that easy:
}
}
1;
__END__
@@ -202,6 +199,81 @@ __END__
SOAP::WSDL::XSD::Typelib::ComplexType - complexType base class
=head1 Subclassing
package MyComplexType;
use Class::Std::Storable
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
__PACKAGE__->_factory(
\@elements_from,
\%attributes_of,
\%classes_of
);
When subclassing, the following methods are created in the subclass:
=head2 new
Constructor. For your convenience, new will accept data for the object's
properties in the following forms:
hash refs
1) of scalars
2) of list refs
3) of hash refs
4) of objects
5) mixed stuff of all of the above
new() will set the data via the set_FOO methods to the object's element
properties.
Data passed to new must comply to the object's structure or new() will
complain. Objects passed must be of the expected type, or new() will
complain, too.
Examples:
my $obj = MyClass->new({ MyName => $value });
my $obj = MyClass->new({
MyName => {
DeepName => $value
},
MySecondName => $value,
});
my $obj = MyClass->new({
MyName => [
{ DeepName => $value },
{ DeepName => $other_value },
],
MySecondName => $object,
MyThirdName => [ $object1, $object2 ],
});
To be correct, SOAP::WSDL::XSD::Typelib::ComplexType will create a START
method, not new() - but new() will be created from Class::Std::Storable and
behave like stated above.
=head2 set_FOO
A mutator method for every element property.
For your convenience, the set_FOO methods will accept all kind of data you
can think of (and all combinations of them) as input - with the exception
of GLOBS and filehandles.
This means you may set element properties by passing
a) objects
b) scalars
c) list refs
d) hash refs
e) mixed stuff of all of the above
Examples are similar to the examples provided for new() above.
=head1 Bugs and limitations
=over