import SOAP-WSDL 2.00_08 from CPAN

git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_08
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_08.tar.gz
This commit is contained in:
Martin Kutter
2009-12-12 19:47:46 -08:00
committed by Michael G. Schwern
parent 40e0e67e84
commit 312f3d6bbd
46 changed files with 1544 additions and 1188 deletions
+46
View File
@@ -0,0 +1,46 @@
package SOAP::WSDL::XSD::Builtin;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
use Data::Dumper;
sub serialize {
my ($self, $name, $value, $opt) = @_;
my $xml;
$opt->{ indent } ||= "";
$opt->{ attributes } ||= [];
$xml .= $opt->{ indent } if ($opt->{ readable });
$xml .= '<' . join ' ', $name, @{ $opt->{ attributes } };
if ( $opt->{ autotype }) {
my $ns = $self->get_targetNamespace();
my $prefix = $opt->{ namespace }->{ $ns }
|| die 'No prefix found for namespace '. $ns;
$xml .= ' type="' . $prefix . ':'
. $self->get_name() . '"' if ($self->get_name() );
}
if (defined $value) {
$xml .= '>';
$xml .= "$value";
$xml .= '</' . $name . '>' ;
}
else {
$xml .= '/>';
}
$xml .= "\n" if ($opt->{ readable });
return $xml;
}
sub explain {
my ($self, $opt, $name ) = @_;
$opt->{ indent } = q{} if not defined $opt->{ indent };
return "$opt->{ indent }'$name' => \$someValue,\n"
}
sub toClass {
warn "# builtin";
}
1;
+11 -30
View File
@@ -127,16 +127,15 @@ sub explain {
return q{} if not $flavor; # empty complexType
$opt->{ indent } ||= q{ };
my $xml = q{};
$xml .= "$opt->{indent}\'$name'=> " if $name;
my $xml = q{};
$xml .= "$opt->{indent}\'$name'=> {\n" if $name;
if ( ($flavor eq "sequence") or ($flavor eq "all") ) {
$xml .= "{\n";
$opt->{ indent } .= " ";
$xml .= join q{}, map { $_->explain( $opt ) }
@{ $self->get_element() };
$opt->{ indent } .= " ";
for my $element (@{ $self->get_element() }) {
$xml .= $element->explain( $opt )
}
$opt->{ indent } =~s/\s{2}$//; # step back
$xml .= "$opt->{ indent }},\n";
}
elsif ($flavor eq "complexContent")
{
@@ -150,6 +149,11 @@ sub explain {
{
warn "found unsupported complexType definition $flavor";
}
# if we're called inside a element...
$xml .= "$opt->{indent}},\n" if $name;
return $xml;
}
@@ -300,26 +304,3 @@ sub _check_value {
}
1;
=pod
=head1 Bugs and limitations
=over
=item * attribute definitions
Attribute definitions are ignored
=item * abstract, block, final, mixed
Handling of these attribute is not implemented yet.
=item * simpleContent, complexContent, extension, restriction, group, choice
Handling of these child elements is not implemented yet
=item * explain may produce erroneous results
=back
=cut
+18 -52
View File
@@ -111,18 +111,24 @@ sub serialize {
sub explain {
my ($self, $opt, $name) = @_;
my $type;
my $text = q{};
my $text = q{};
# if we have a simple / complexType, explain right here
if ($type = $self->first_simpleType() )
{
$text .= $type->explain( $opt, $self->get_name() );
return $text;
if ($opt->{ anonymous }) {
delete $opt->{ anonymous };
return $type->explain( $opt, undef );
}
return $type->explain( $opt, $self->get_name() );
}
elsif ($type = $self->first_complexType() )
{
$text .= $type->explain( $opt, $self->get_name() );
return $text;
if ($opt->{ anonymous }) {
delete $opt->{ anonymous };
return $type->explain( $opt, undef );
}
return $type->explain( $opt, $self->get_name() );
}
# return if it's not a derived type - we don't handle
@@ -137,12 +143,15 @@ sub explain {
$ns_map{ $prefix }, $localname
);
use Data::Dumper;
use Data::Dumper;
die "no type for $prefix:$localname ($ns_map{ $prefix })"
. Dumper $opt->{ wsdl }->first_types()->first_schema()->_DUMP
if (not $type);
if (not $type);
if ($opt->{ anonymous }) {
delete $opt->{ anonymous };
return $text .= $type->explain( $opt, undef );
}
return $text .= $type->explain( $opt, $self->get_name() );
return 'ERROR: '. $@;
}
@@ -369,47 +378,4 @@ EOT
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::XSD::Element - XSD Element representation
=head1 DESCRIPTION
Represents a XML Schema Definition's Element element for serializing into
various forms.
=head1 Bugs and limitations
=over
=item * block
Handling of the block attribute is not implemented yet.
=item * final
Handling of the final attribute is not implemented yet.
=item * substitutionGroup
Handling of the substitutionGroup attribute is not implemented yet
=item * explain may produce erroneous results
=back
=head1 COPYING
This module is part of SOAP-WSDL. See SOAP::WSDL for license.
=head1 AUTHOR
Insert @ instead of whitespace into e-mail.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut
-50
View File
@@ -1,50 +0,0 @@
package SOAP::WSDL::XSD::Primitive;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
use Data::Dumper;
sub serialize
{
my ($self, $name, $value, $opt) = @_;
my $xml;
$opt->{ indent } ||= "";
$opt->{ attributes } ||= [];
$xml .= $opt->{ indent } if ($opt->{ readable });
$xml .= '<' . join ' ', $name, @{ $opt->{ attributes } };
if ( $opt->{ autotype })
{
my $ns = $self->get_targetNamespace();
my $prefix = $opt->{ namespace }->{ $ns }
|| die 'No prefix found for namespace '. $ns;
$xml .= ' type="' . $prefix . ':'
. $self->get_name() . '"' if ($self->get_name() );
}
if (defined $value)
{
$xml .= '>';
$xml .= "$value";
$xml .= '</' . $name . '>' ;
}
else
{
$xml .= '/>';
}
$xml .= "\n" if ($opt->{ readable });
return $xml;
}
sub explain
{
my ($self, $opt, $name ) = @_;
$opt->{ indent } ||= "";
return "$opt->{ indent }'$name' => \$someValue,\n"
}
sub toClass {
warn "# primitive";
}
1;
+4 -4
View File
@@ -3,11 +3,11 @@ use strict;
use warnings;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Schema;
use SOAP::WSDL::XSD::Primitive;
use SOAP::WSDL::XSD::Builtin;
use base qw(SOAP::WSDL::XSD::Schema);
# all builtin types - add validation (e.g. content restrictions) later...
my %PRIMITIVES = (
my %BUILTINS = (
'string' => {},
'boolean' => {},
'decimal' => {},
@@ -50,9 +50,9 @@ sub START {
my $self = shift;
my @args = @_;
while (my ($name, $value) = each %PRIMITIVES )
while (my ($name, $value) = each %BUILTINS )
{
$self->push_type( SOAP::WSDL::XSD::Primitive->new({
$self->push_type( SOAP::WSDL::XSD::Builtin->new({
name => $name,
targetNamespace => 'http://www.w3.org/2001/XMLSchema',
} )
+4 -30
View File
@@ -43,8 +43,7 @@ sub set_union {
}
}
sub push_enumeration
{
sub push_enumeration {
my $self = shift;
my @attr = @_;
my @attributes = @_;
@@ -101,13 +100,9 @@ sub _serialize_single {
}
sub explain {
my ($self, $opt, $name) = @_;
my $perl;
$opt->{ indent } ||= "";
$perl .= $opt->{ indent } if ($opt->{ readable });
$perl .= q{'} . $name . q{' => $someValue };
$perl .= "\n" if ($opt->{ readable });
return $perl;
my ($self, $opt, $name ) = @_;
$opt->{ indent } = q{} if not defined $opt->{ indent };
return "$opt->{ indent }'$name' => \$someValue,\n"
}
sub _check_value {
@@ -155,25 +150,4 @@ EOT
return $code;
}
1;
=pod
=head1 Bugs and limitations
=over
=item * simpleContent, complexContent
These child elements are not implemented yet
=item * union
union simpleType definitions probalbly serialize wrong
=item * explain may produce erroneous results
=back
=cut
+33
View File
@@ -205,7 +205,26 @@ byte integer objects.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::date
date values are automatically converted into XML date strings during setting:
YYYY-MM-DD+zz:zz
The time zone is set to the local time zone if not included.
All input variants supported by Date::Parse are supported. You may even pass
in dateTime strings - the time part will be ignored. Note that
set_value is around 100 times slower when setting non-XML-time strings
=head2 SOAP::WSDL::XSD::Typelib::Builtin::dateTime
dateTime values are automatically converted into XML dateTime strings during setting:
YYYY-MM-DDThh:mm:ss.nnnnnnn+zz:zz
The optional nanoseconds parts is excluded in converted values, as it would always be 0.
All input variants supported by Date::Parse are supported. Note that
set_value is around 100 times slower when setting non-XML-time strings
=head2 SOAP::WSDL::XSD::Typelib::Builtin::decimal
@@ -237,6 +256,8 @@ decimal is the base of all non-float numbers
=head2 SOAP::WSDL::XSD::Typelib::Builtin::IDREFS
List of SOAP::WSDL::XSD::Typelib::Builtin::IDREF objects.
Derived by SOAP::WSDL::XSD::Typelib::Builtin::list.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::int
@@ -273,6 +294,18 @@ Derived by SOAP::WSDL::XSD::Typelib::Builtin::list.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::time
time values are automatically converted into XML time strings during setting:
hh:mm:ss.nnnnnnn+zz:zz
hh:mm:ss+zz:zz
The time zone is set to the local time zone if not included. The optional
nanoseconds part is not included in converted values, as it would always be 0.
All input variants supported by Date::Parse are supported. You may even pass
in dateTime strings - the date part will be ignored. Note that
set_value is around 100 times slower when setting non-XML-time strings
=head2 SOAP::WSDL::XSD::Typelib::Builtin::token
=head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte
+30
View File
@@ -2,6 +2,9 @@ package SOAP::WSDL::XSD::Typelib::Builtin::date;
use strict;
use warnings;
use Date::Parse;
use Date::Format;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
@@ -31,5 +34,32 @@ 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
if (
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
(:? [\+\-] \d{2} \: \d{2} )?
}xms
) {
$_[0]->SUPER::set_value($_[1])
}
# use a combination of strptime and strftime for converting the date
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
# whants it as [+-]00:00
# We know that the latter part of the TZ is always :00 (there's no time
# zone whith minute offset yet), so we just use substr to get the part
# up to the last 2 timezone digits and append :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_str = strftime( '%Y-%m-%d%z', @time_from );
substr $time_str, -2, 0, ':';
$_[0]->SUPER::set_value($time_str);
}
}
1;
+28 -3
View File
@@ -3,6 +3,8 @@ use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
use Date::Parse;
use Date::Format;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
@@ -30,8 +32,31 @@ BEGIN {
}
return $self;
};
}
sub set_value {
# use set_value from base class if we have a XML-DateTime format
#2037-12-31T00:00:00.0000000+01:00
if (
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
T \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
[\+\-] \d{2} \: \d{2} $
}xms
) {
$_[0]->SUPER::set_value($_[1])
}
# use a combination of strptime and strftime for converting the date
# 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_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from );
substr $time_str, -2, 0, ':';
$_[0]->SUPER::set_value($time_str);
}
}
1;
+28
View File
@@ -1,6 +1,8 @@
package SOAP::WSDL::XSD::Typelib::Builtin::time;
use strict;
use warnings;
use Date::Parse;
use Date::Format;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
@@ -30,4 +32,30 @@ BEGIN {
};
}
sub set_value {
# use set_value from base class if we have a XML-Time format
# 00:00:00.0000000+01:00
if (
$_[1] =~ m{ ^ \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
[\+\-] \d{2} \: \d{2} $
}xms
) {
$_[0]->SUPER::set_value($_[1])
}
# use a combination of strptime and strftime for converting the date
# 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...
# we even need to set it to 1 to prevent a "Day '0' out of range 1..31" warning...
my @time_from = map { ! defined $_ ? 1 : $_ } strptime($_[1]);
my $time_str = strftime( '%H:%M:%S%z', @time_from );
substr $time_str, -2, 0, ':';
$_[0]->SUPER::set_value($time_str);
}
}
1;
+57 -33
View File
@@ -29,46 +29,70 @@ sub _factory {
my $type = $CLASSES_OF{ $class }->{ $name }
or die "No class given for $name";
# require all types here - this is a slow check -
# TODO speedup
$type->isa('UNIVERSAL')
or eval "require $type"
or croak $@;
my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list');
*{ "$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
# c) list refs
# d) hash refs
# e) mixed stuff of all of the above, so we have to
# set our element to
# a) value if it's an object
# b) New object with value for simple values
# c 1) New object with value for list values and list type
# c 2) List ref of new objects with value for list values and non-list type
# c + e) List ref of objects for list values (list of objects) and non-list type
# d) New object with values passed to new for HASH references
#
# Die on non-ARRAY/HASH references - if you can define semantics
# for GLOB references, feel free to add them.
$attribute_ref->{ ident $self } = blessed $value
? $value
: ref $value
? ref $value eq 'ARRAY'
? $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list')
? $type->new({ value => $value })
: [ map {
blessed($_)
? ($_->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
? $_
: croak 'cannot use non-XSD object as value'
: $type->new({ value => $_ })
} @{ $value }
]
: ref $value eq 'HASH'
we accept:
a) objects
b) scalars
c) list refs
d) hash refs
e) mixed stuff of all of the above, so we have to set our element to
a) value if it's an object
b) New object of expected class with value for simple values
c 1) New object with value for list values and list type
c 2) List ref of new objects with value for list values and non-list type
c + e 1) List ref of objects for list values (list of objects) and non-list type
c + e 2) List ref of new objects for list values (list of hashes) and non-list type
where the hash ref is passed to new as argument
d) New object with values passed to new for HASH references
We throw an error on
a) list refs of list refs - don't know what to do with this (maybe use for lists of list types ?)
b) wrong object types
c) non-blessed non-ARRAY/HASH references - if you can define semantics
for GLOB references, feel free to add them.
d) we should also die for non-blessed non-ARRAY/HASH references in lists but don't do yet - oh my !
=cut
my $is_ref = ref $value;
$attribute_ref->{ ident $self } = ($is_ref)
? $is_ref eq 'ARRAY'
? $is_list
? $type->new({ value => $value })
: [ map {
ref $_
? ref $_ eq 'HASH'
? $type->new($_)
: ref $_ eq $type
? $_
: croak "cannot use " . ref($_) . " reference as value for $name - $type required"
: $type->new({ value => $_ })
} @{ $value }
]
: $is_ref eq 'HASH'
? $type->new( $value )
: die 'Cannot use non-ARRAY/HASH as data'
: $is_ref eq $type
? $value
: die 'Cannot use non-ARRAY/HASH as data'
: $type->new({ value => $value });
};
@@ -176,7 +200,7 @@ __END__
=head1 NAME
SOAP::WSDL::XSD::Typelib::ComplexType - ComplexType XML Schema definitions
SOAP::WSDL::XSD::Typelib::ComplexType - complexType base class
=head1 Bugs and limitations
+47 -3
View File
@@ -63,27 +63,71 @@ sub end_tag {
1;
=pod
=head1 NAME
SOAP::WSDL::XSD::Typelib::Element - element base clase
=head1 SYNOPSIS
This example creates a class for this XML schema definition:
<element name="MyElement" type="xsd:string" nillable="1"
minOccurs="1" maxOccurs="1"/>
package MyElement;
use strict;
use Class::Std::Storable;
use base (
'SOAP::WSDL::XSD::Typelib::Element',
'SOAP::WSDL::XSD::Typelib::Element',
'SOAP::WSDL::XSD::Typelib::Builtin::string',
);
__PACKAGE__->__set_name('MyElementName');
__PACKAGE__->__set_nillable(1);
__PACKAGE__->__set_minOccurs(1);
__PACKAGE__->__set_maxOccurs(1);
__PACKAGE__->__set_ref(1);
__PACKAGE__->__set_ref(0);
Now we create this XML schema definition type class:
<element name="MyElement2" ref="tns:MyElement"/>
package MyElement2;
use strict;
use Class::Std::Storable;
use base (
'SOAP::WSDL::XSD::Typelib::Element',
'MyElement'
);
__PACKAGE__->__set_name('MyElementName');
__PACKAGE__->__set_nillable(0);
__PACKAGE__->__set_ref(1);
=head1 NOTES
=over
=item * type="Foo"
Implemented via inheritance.
=item * ref="Foo"
Implemented via inheritance, too. Calling
__PACKAGE__->__set_ref(1) is highly encouraged, though it has no
effect yet - it will probably be needed for serialization to XML
Schema definitions some day.
=back
=head1 BUGS AND LIMITATIONS
=over
=item * minOccurs maxOccurs ref not implemented
=item * minOccurs maxOccurs not implemented
These attributes are not yet supported, though they may be set as class
properties via __PACKAGE__->__set_FOO methods.
+1 -1
View File
@@ -17,7 +17,7 @@ __END__
=head1 NAME
SOAP::WSDL::XSD::Typelib::SimpleType - simple type base class
SOAP::WSDL::XSD::Typelib::SimpleType - simpleType base class
=head1 DESCRIPTION