SOAP-WSDL-3.004004075500017500001750000000000001361135364200120745ustar00scottscottSOAP-WSDL-3.004/lib004075500017500001750000000000001361135364000126405ustar00scottscottSOAP-WSDL-3.004/lib/SOAP004075500017500001750000000000001361135364100134035ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL004075500017500001750000000000001361135364200141555ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator004075500017500001750000000000001361135364200161035ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template004075500017500001750000000000001361135364200176565ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD004075500017500001750000000000001361135364200203145ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server.tt010064400017500001750000000051711237511274000222110ustar00scottscott[% USE XSD; server_name = XSD.create_server_name(service, port); -%] package [% server_name %]; use strict; use warnings; use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before require [% XSD.create_typemap_name(service) %] if not [% XSD.create_typemap_name(service) %]->can('get_class'); my %transport_class_of :ATTR(:name :default); my %transport_of :ATTR(:name :default<()>); my %dispatch_to :ATTR(:name); my $action_map_ref = { [% binding = definitions.find_binding( port.expand( port.get_binding ) ); FOREACH operation = binding.get_operation; - %] '[% operation.first_operation.get_soapAction %]' => '[% operation.get_name %]', [% END %] }; sub START { my ($self, $ident, $arg_ref) = @_; eval "require $transport_class_of{ $ident }" or die "Cannot load transport class $transport_class_of{ $ident }: $@"; $transport_of{ $ident } = $transport_class_of{ $ident }->new({ action_map_ref => $action_map_ref, class_resolver => '[% XSD.create_typemap_name(service) %]', dispatch_to => $dispatch_to{ $ident }, }); } sub handle { $transport_of{ ${ $_[0] } }->handle(@_[1..$#_]); } 1; [% IF NO_POD; STOP; END %] __END__ [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% pod = BLOCK %]=pod[% END -%] [% head1 = BLOCK %]=head1[% END -%] [% head2 = BLOCK %]=head2[% END -%] [% head3 = BLOCK %]=head3[% END -%] [% pod %] [% head1 %] NAME [% server_name %] - SOAP Server Class for the [% service.get_name %] Web Service [% head1 %] SYNOPSIS use [% server_name %]; my $server = [% server_name %]->new({ dispatch_to => 'My::Handler::Class', transport_class => 'SOAP::WSDL::Server::CGI', # optional, default }); $server->handle(); [% head1 %] DESCRIPTION SOAP Server handler for the [% service.get_name %] web service located at [% port.first_address.get_location %]. [% head1 %] SERVICE [% service.get_name %] [% service.get_documentation %] [% head2 %] Port [% port.get_name %] [% port.get_documentation %] [% head1 %] METHODS [% head2 %] General methods [% head3 %] new Constructor. The C argument is mandatory. It must be a class or object implementing the SOAP Service methods listed below. [% head2 %] SOAP Service methods [% INCLUDE Server/POD/method_info.tt %] [% FOREACH operation = binding.get_operation; %][% INCLUDE Server/POD/Operation.tt %] [% END %] [% head1 %] AUTHOR Generated by SOAP::WSDL on [% PERL %]print scalar localtime() [% END %] =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType004075500017500001750000000000001361135364200224475ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt010064400017500001750000000006351237511274000255310ustar00scottscott[% IF (simpleType.get_variety == 'list'); INCLUDE simpleType/list.tt(simpleType = simpleType); ELSIF (simpleType.get_variety == 'restriction'); INCLUDE simpleType/restriction.tt(type = simpleType); ELSIF (simpleType.get_variety == 'union'); INCLUDE simpleType/union.tt(type = simpleType); ELSE; THROW NOT_IMPLEMENTED "${ element.get_name } - ${ simpleType.get_variety } not supported yet"; END %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD004075500017500001750000000000001361135364200230715ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt010064400017500001750000000010631237511274000260610ustar00scottscottThis clase is derived from [%- IF (name = simpleType.get_base); type = definitions.get_types.0.find_type(simpleType.expand(name)); %] [% XSD.create_xsd_name(type); %] [% ELSE; # THROW NOT_IMPLEMENTED "atomic simpleType restriction not implemented yet in $simpleType.get_name"; %] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [% END -%] . SOAP::WSDL's schema implementation does not validate data, so you can use it exactly like it's base type. # Description of restrictions not implemented yet.SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/structure.tt010064400017500001750000000001301237511274000255460ustar00scottscott$some_value, # [% IF (simpleType.get_name); simpleType.get_name; ELSE %]atomic[% END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt010064400017500001750000000011041237511274000244630ustar00scottscottThis clase is derived from [%- IF (name = simpleType.get_itemType); type = definitions.get_types.0.find_type(simpleType.expand( name )); %] [% XSD.create_xsd_name(type) %] [% ELSE; # THROW NOT_IMPLEMENTED "atomic simpleType list not implemented yet in $simpleType.get_name"; %] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [% END -%]. You may pass the following structure to new(): [ $value_1, .. $value_n ] All elements of the list must be of the class' base type (or valid arguments to it's constructor). SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt010064400017500001750000000005331237511274000246450ustar00scottscottThis type class is derived by union. Derivation by union is not fully supported yet - value space constraints are not checked yet. The current implementation of union resorts to inheriting from the base type, which means (quoted from the XML Schema specs): "If the or alternative is chosen, then the simple ur-type definition·." SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt010064400017500001750000000005731237511274000261540ustar00scottscott[% IF (simpleType.get_variety == 'list'); INCLUDE simpleType/POD/list.tt; ELSIF (simpleType.get_variety == 'restriction'); INCLUDE simpleType/POD/restriction.tt; ELSIF (simpleType.get_variety == 'union'); INCLUDE simpleType/POD/union.tt; ELSE; # THROW NOT_IMPLEMENTED "simpleType " _ simpleType.get_variety _ "not implemented yet in $simpleType.get_name"; END %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/atomicType.tt010064400017500001750000000001251237511274000252060ustar00scottscott# atomic simple type. [% INCLUDE simpleType/contentModel.tt(simpleType = type ); %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt010064400017500001750000000007671237511274000254510ustar00scottscott# derivation by restriction [% IF (base = simpleType.get_base) -%] use base qw( [% base_type = definitions.get_types.0.find_type(simpleType.expand(base)); IF ! base_type; THROW NOT_FOUND "base type $base not found." _ simpleType.get_parent.get_name; END; XSD.create_xsd_name(base_type) %]); [% ELSIF (type = simpleType.first_simpleType() ); INCLUDE simpleType/atomicType.tt(type = type); ELSE; THROW "neither base nor atomic type - don't know what to do" %] [% END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt010064400017500001750000000007621237511274000240520ustar00scottscott[% USE XSD %] # list derivation use base qw( SOAP::WSDL::XSD::Typelib::Builtin::list [% IF (name = simpleType.get_itemType); type = definitions.get_types.0.find_type(simpleType.expand( name )); -%] [% XSD.create_xsd_name(type) %] ); [% ELSIF (type = simpleType.first_simpleType); %] ); [% INCLUDE simpleType/atomicType.tt(type = type); ELSE; PERL %]die $stash->{simpleType}._DUMP [% END; THROW UNKNOWN , "No list itemTape and no atomic simpleType - don't know what to do"; END %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt010064400017500001750000000005361237511274000242260ustar00scottscott# derivation by union # union is not fully supported yet - value space constraints are not # checked yet. # This implementation of union resorts to the simplest possible base, which # is: "If the or alternative is chosen, then the # simple ur-type definition·." # use base qw( SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType ); SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType004075500017500001750000000000001361135364200226255ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD004075500017500001750000000000001361135364200232475ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/complexContent.tt010064400017500001750000000007011237511274000266720ustar00scottscott[% IF (complexType.get_derivation == 'restriction'); INCLUDE complexType/POD/restriction.tt(complexType = complexType); ELSIF (complexType.get_derivation == 'extension'); #THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType complexContent extension not implemented yet"; %] # No documentation generated for complexContent / extension yet [% ELSE; THROW UNKNOWN, "unknown derivation ${ complexType.get_derivation }"; END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent004075500017500001750000000000001361135364200260735ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt010064400017500001750000000024451237511274000310700ustar00scottscott { value => $some_value, # simple perl scalar. See below for restrictions } NOTE: This type is derived by restriction as complexType with simpleContent. Documentation generation for this derivation method is experimental and may be erroneous/incomplete. This clase is derived from [%- IF (name = complexType.get_base); # type_name = complexType.expand( name ); -%] [% XSD.create_xsd_name(complexType) %] [% ELSE; %] an atomic base type. Unfortunately there's no documentation generated on atomic base types' base type yet.[% END -%] SOAP::WSDL's schema implementation does not validate data yet - however, the following restrictions apply for this type's value: [%- FOREACH facet = [ 'length', 'minLength', 'maxLength', 'totalDigits', 'fractionDigits', 'minInclusive', 'maxInclusive', 'minExclusive', 'maxExclusive', 'pattern', 'enumeration' ]; IF (facet_method = complexType.can( "get_" _ facet )); facet_value = facet_method( complexType ); IF (facet_value.size()); %] [% IF (facet == 'enumeration'); %]valid values (enumeration) [%- ELSE; facet; END -%]:[% FOREACH value = facet_value %] [% value.get_value; END -%] [% END; END; END %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt010064400017500001750000000000761237511274000305350ustar00scottscott# No documentation generated for simpleContent / extension yetSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt010064400017500001750000000004441237511274000262410ustar00scottscott[% indent %]{ [%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' '; FOREACH element = complexType.get_element %] [% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%] [% END %] [% indent.replace('\s{2}$', ''); %]}SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt010064400017500001750000000013461237511274000257360ustar00scottscott[% IF (complexType.get_variety == 'all'); INCLUDE complexType/POD/all.tt(complexType = complexType); ELSIF (complexType.get_variety == 'sequence'); INCLUDE complexType/POD/all.tt(complexType = complexType); ELSIF (complexType.get_variety == 'group'); THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType group not implemented yet"; ELSIF (complexType.get_variety == 'choice'); INCLUDE complexType/POD/choice.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'simpleContent'); INCLUDE complexType/POD/structure/simpleContent.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'complexContent'); INCLUDE complexType/POD/complexContent.tt(complexType = complexType); END -%],SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure004075500017500001750000000000001361135364200253075ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt010064400017500001750000000004301237511274000302740ustar00scottscott{ [%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' '; FOREACH element = complexType.get_element %] [% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%] [% END %] [% indent.replace('\s{2}$', ''); %]}SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt010064400017500001750000000000311237511274000305500ustar00scottscott { value => $some_value }SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt010064400017500001750000000007101361134503300251170ustar00scottscott[%USE XSD -%] [% indent %]{ [%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' ' %] [% indent %]# One of the following elements. [% indent %]# No occurrence checks yet, so be sure to pass just one... [%- FOREACH element = complexType.get_element %] [% indent %][% XSD.perl_var_name(XSD.element_name(element)) %] => [% INCLUDE element/POD/structure.tt -%] [% END %] [% indent.replace('\s{2}$', ''); %]}SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt010064400017500001750000000022761237511274000263600ustar00scottscott[% head2 = BLOCK %]=head2[% END -%] [% IF (complexType.get_attribute.size) %] [% head2 %] attr NOTE: Attribute documentation is experimental, and may be inaccurate. See the correspondent WSDL/XML Schema if in question. This class has additional attributes, accessibly via the C method. attr() returns an object of the class [% XSD.create_xmlattr_name(complexType) %]. The following attributes can be accessed on this object via the corresponding get_/set_ methods: =over [% FOREACH element = complexType.get_attribute; WHILE element.get_ref; element = definitions.first_types.find_attribute(element.expand( element.get_ref )); END; -%] =item * [% element.get_name %] [%- IF (element.get_annotation && element.get_annotation.0.get_documentation) %] [% element.get_annotation.0.get_documentation %] [% END; %] [% IF (type_name=element.get_type); type = definitions.get_types.0.find_type(element.expand(type_name)); IF (! type); THROW NOT_FOUND "type " _ type_name _ " for attribute " _ element.get_name _ " not found"; END; %] This attribute is of type L<[% XSD.create_xsd_name(type) %]|[% XSD.create_xsd_name(type) %]>. [% END %] [%- END -%] =back [% END %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt010064400017500001750000000005351237511274000265210ustar00scottscott[% IF (complexType.get_variety == 'restriction'); INCLUDE complexType/POD/simpleContent/restriction.tt(complexType = complexType); ELSIF (complexType.get_variety == 'extension'); INCLUDE complexType/POD/simpleContent/restriction.tt(complexType = complexType); ELSE; THROW UNKNOWN, "unknown variety ${ complexType.get_variety }"; END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt010064400017500001750000000005041237511274000244410ustar00scottscott[% USE XSD -%] { [%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' '; FOREACH element = complexType.get_element %] [% indent %][% XSD.perl_var_name(XSD.element_name(element)) %] => [% INCLUDE element/POD/structure.tt -%] [% END %] [% indent.replace('\s{2}$', ''); %]}SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/content_model.tt010064400017500001750000000000001237511274000265120ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/complexContent.tt010064400017500001750000000011351237511274000262520ustar00scottscott[% IF (complexType.get_variety == 'restriction'); INCLUDE complexType/restriction.tt(complexType = complexType); ELSIF (complexType.get_variety == 'extension'); INCLUDE complexType/extension.tt(complexType = complexType); ELSIF (complexType.get_variety == 'sequence'); INCLUDE complexType/extension.tt(complexType = complexType); ELSIF (complexType.get_variety == 'all'); INCLUDE complexType/extension.tt(complexType = complexType); ELSE; IF (complexType.get_variety); THROW UNKNOWN, "unknown variety ${ complexType.get_variety }"; ELSE -%] # empty variety [% END; END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent004075500017500001750000000000001361135364100254505ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt010064400017500001750000000004471237511274000301150ustar00scottscott[% IF (base=complexType.get_base); base_type=definitions.get_types.0.find_type(complexType.expand(base)); -%] use base qw( SOAP::WSDL::XSD::Typelib::ComplexType [% XSD.create_xsd_name(base_type) %] ); [% ELSE; THROW NOT_IMPLEMENTED, "extension without base not supported"; END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt010064400017500001750000000044541237511274000240270ustar00scottscottuse Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); Class::Std::initialize(); { # BLOCK to scope variables [% atomic_types = {}; FOREACH element = complexType.get_element; name = XSD.perl_var_name(XSD.element_name(element)); %] my %[% XSD.perl_name(name) %]_of :ATTR(:get<[% XSD.perl_name(name) %]>); [%- END %] __PACKAGE__->_factory( [ qw([% FOREACH element = complexType.get_element; # ugly copied code - macro or plugin method? name = XSD.perl_var_name(XSD.element_name(element)); -%] [% name %] [% END %] ) ], { [% FOREACH element = complexType.get_element; # ugly copied code - macro or plugin method? name = XSD.perl_var_name(XSD.element_name(element)); -%] '[% name %]' => \%[% XSD.perl_name(name) %]_of, [% END -%] }, { [% FOREACH element = complexType.get_element; IF (ref = element.get_ref); ref_element = definitions.first_types.find_element(element.expand( ref )); -%] '[% XSD.perl_var_name(XSD.element_name(ref_element)) %]' => '[% XSD.create_xsd_name(ref_element) %]', [% ELSIF (type = element.get_type); element_type = definitions.first_types.find_type(complexType.expand( type )); IF (! element_type); type_name = complexType.expand( type ); THROW NOT_FOUND, "${ type_name.0 } ${ type_name.1 } not found"; END; -%] '[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_xsd_name(element_type) %]', [% ELSE; IF (element.first_simpleType); atomic_types.${ element.get_name } = element.first_simpleType; ELSIF (element.first_complexType); atomic_types.${ element.get_name } = element.first_complexType; ELSE; THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for element ${ element.get_name } - don't know what to do with it"; END; %] '[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_subpackage_name({ value => element }) %]', [% END; END -%] }, { [% FOREACH element = complexType.get_element; %] '[% XSD.perl_var_name(XSD.element_name(element)); %]' => '[% element.get_name %]', [%- END %] } ); } # end BLOCK [% INCLUDE complexType/atomicTypes.tt(atomic_types = atomic_types) %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt010064400017500001750000000036661237511274000257420ustar00scottscott[% IF (complexType.get_attribute.size) -%] package [% XSD.create_xmlattr_name(complexType) %]; use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); { # BLOCK to scope variables [% FOREACH element = complexType.get_attribute; WHILE element.get_ref; element = definitions.first_types.find_attribute(element.expand( element.get_ref )); END; %] my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>); [%- END %] __PACKAGE__->_factory( [ qw( [%- FOREACH element = complexType.get_attribute; WHILE element.get_ref; element = definitions.first_types.find_attribute(element.expand( element.get_ref )); END; %] [% element.get_name -%] [% END %] ) ], { [% FOREACH element = complexType.get_attribute; WHILE element.get_ref; element = definitions.first_types.find_attribute(element.expand( element.get_ref )); END; %] [% element.get_name %] => \%[% element.get_name %]_of, [% END -%] }, { [% FOREACH element = complexType.get_attribute; IF (type = element.get_type); element_type = definitions.first_types.find_type(complexType.expand( type )); -%] [% element.get_name %] => '[% XSD.create_xsd_name(element_type) %]', [% ELSIF (ref = element.get_ref); WHILE element.get_ref; element = definitions.first_types.find_attribute(element.expand( element.get_ref )); END; %] [% element.get_name %] => '[% XSD.create_xsd_name(element) %]', [% ELSIF (element.first_simpleType); THROW NOT_IMPLEMENTED , "Attributes with atomic simpleType definition are not implemented yet"; atomic_types.${ element.get_name } = element.first_simpleType; ELSE; THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for attribute ${ element.get_name } in ${ complexType.get_name } - don't know what to do with it"; END; END -%] } ); } # end BLOCK [% END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt010064400017500001750000000007461237511274000261030ustar00scottscott[% IF (complexType.get_variety == 'restriction'); INCLUDE complexType/restriction.tt(complexType = complexType); ELSIF (complexType.get_variety == 'extension'); INCLUDE complexType/simpleContent/extension.tt(complexType = complexType); # THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType simpleContent extension not implemented yet"; ELSE; THROW UNKNOWN, "unknown variety ${ complexType.get_variety } in complexType name='${complexType.get_name}'"; END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt010064400017500001750000000041451237511274000252700ustar00scottscott[% # # extension # # unfortunately, SOAP::WSDL's speed tweaks don't play well with # Class::Std's inheritance model. # # In Class::Std, all properties are stored in the class, and in objects # using inheritance in the defining class. # # As the speed tweaks directly access the class' data without checking # inheritance, the simplest way is to resolve complexType extension # relationships # # To capture deep inheritance, extensions must be followed until a non- # extension base is found # # TODO attribute handling is missing # TODO sort out some better way to handle inheritance element_list = []; # copy complexType ref base_type = complexType; base_name = base_type.expand( base_type.get_base ); base_type = definitions.first_types.find_type( base_name ); # add a use base for first to setup inheritance %] use base qw([% XSD.create_xsd_name( base_type ) %]); [% # loop forever WHILE (1); IF (complexType.get_variety == 'extension'); # wrap statement in IF to avoid printing IF (complexType.set_variety( base_type.get_variety )); END; END; # make a copy. We don't want to modify the original list here... FOREACH element = base_type.get_element.reverse; element_list.unshift(element); END; # get next base type if there is one... IF (base_type.get_base); base_name=base_type.expand( base_type.get_base ); # set new base_type base_type = definitions.first_types.find_type( base_name ); ELSE; # exit loop if there is none BREAK; END; END; # # and now the new elements... # element_from = complexType.get_element; FOREACH element = element_from; IF element_list.${ loop.index }.get_name != element.get_name; element_list.push( element ); END; END; # set derived element list # wrap in IF; END; to prevent it getting printed IF ( complexType.set_element( element_list ) ); END; -%] # Variety: [% complexType.get_variety %] [% INCLUDE complexType/variety.tt(complexType = complexType); # restore original element list # wrap in IF; END; to prevent it getting printed IF ( complexType.set_element( element_from ) ); END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt010064400017500001750000000010521237511274000255470ustar00scottscott [% FOREACH type IN atomic_types; %] [%# TODO generate name create_name method %] package [% XSD.create_subpackage_name(type); %]; use strict; use warnings; { [% IF ( type.value.isa('SOAP::WSDL::XSD::ComplexType') ); INCLUDE complexType/contentModel.tt(complexType = type.value ); ELSIF ( type.value.isa('SOAP::WSDL::XSD::SimpleType') ); INCLUDE simpleType/contentModel.tt(simpleType = type.value ); ELSE; PERL; %] die $stash->{ type } [% END; THROW UNKNOWN, "neither complex nor simple type - don't know what to do"; END %] } [% END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt010064400017500001750000000003711237511274000256160ustar00scottscott[% IF (base=complexType.get_base); base_type=definitions.get_types.0.find_type(complexType.expand(base)); -%] use base qw([% XSD.create_xsd_type(base_type) %]); [% ELSE; THROW NOT_IMPLEMENTED, "restriction without base not supported"; END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt010064400017500001750000000011611237511274000257020ustar00scottscott[% IF (complexType.get_attribute.size) -%] our $XML_ATTRIBUTE_CLASS = '[% XSD.create_xmlattr_name(complexType) %]'; [% ELSE -%] our $XML_ATTRIBUTE_CLASS; undef $XML_ATTRIBUTE_CLASS; [% END %] sub __get_attr_class { return $XML_ATTRIBUTE_CLASS; } [% IF (complexType.get_contentModel == 'simpleContent'); INCLUDE complexType/simpleContent.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'complexContent'); INCLUDE complexType/complexContent.tt(complexType = complexType); ELSE; INCLUDE complexType/variety.tt(complexType = complexType); END -%] [% INCLUDE complexType/attributeSet.tt %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType/variety.tt010064400017500001750000000014421237511274000247340ustar00scottscott[% IF (complexType.get_variety == 'all'); INCLUDE complexType/all.tt(complexType = complexType); ELSIF (complexType.get_variety == 'sequence'); INCLUDE complexType/all.tt(complexType = complexType); ELSIF (complexType.get_variety == 'group'); THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType group not implemented yet"; ELSIF (complexType.get_variety == 'choice'); INCLUDE complexType/all.tt(complexType = complexType); #ELSIF (complexType.get_variety); # THROW NOT_IMPLEMENTED, "unknown variety ${ complexType.get_variety } in ${ complexType.get_name } (${ element.get_name })"; ELSE %] # There's no variety - empty complexType use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); __PACKAGE__->_factory(); [% END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt010064400017500001750000000023701237511274000230740ustar00scottscott[% USE XSD(context) -%] package [% XSD.create_xsd_name(simpleType) %]; use strict; use warnings; sub get_xmlns { '[% simpleType.get_targetNamespace %]'}; [% INCLUDE simpleType/contentModel.tt %] [%# # Don't include any perl source here - there may be sub-packages... #-%] 1; __END__ [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% pod = BLOCK %]=pod[% END -%] [% head1 = BLOCK %]=head1[% END -%] [% head2 = BLOCK %]=head2[% END -%] [% head3 = BLOCK %]=head3[% END -%] [% pod %] [% head1 %] NAME [% XSD.create_name(simpleType) %] [% head1 %] DESCRIPTION Perl data type class for the XML Schema defined simpleType [% simpleType.get_name %] from the namespace [% simpleType.get_targetNamespace %]. [% INCLUDE POD/annotation.tt(node = simpleType) %] [% INCLUDE simpleType/POD/contentModel.tt(simpleType = simpleType) %] [% head1 %] METHODS [% head2 %] new Constructor. [% head2 %] get_value / set_value Getter and setter for the simpleType's value. [% head1 %] OVERLOADING Depending on the simple type's base type, the following operations are overloaded Stringification Numerification Boolification Check L for more information. [% head1 %] AUTHOR Generated by SOAP::WSDL =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface004075500017500001750000000000001361135364200222145ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt010064400017500001750000000033761237511274000240400ustar00scottscott[% RETURN IF NOT item; message_name = item.get_message; IF NOT message_name; THROW BAD_WSDL "missing attribute in header for operation ${operation.get_name}"; END; message = definitions.find_message( item.expand( message_name ) ); PERL %] my $message = $stash->{ message }; my $item = $stash->{ item }; my $def = $stash->{ definitions }; my $type_prefix = $stash->{ type_prefix }; my $element_prefix = $stash->{ element_prefix }; #my ($ns, $lname) = $def->expand( $item->get_part() ); my $part_name = $item->get_part(); my ($part) = grep { $_->get_name eq $part_name } @{ $message->get_part( ) }; my $part_class = do { my $name; ($name = $part->get_element) ? do { my $element = $def->first_types->find_element($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : ($name = $part->get_type) ? do { my $element = $def->first_types->find_type($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : die "input must have either type or element" }; $stash->{ part_class } = $part_class; [% END; %] [% IF item.get_use != 'literal'; THROW NOT_SUPPORTED "Header: SOAP::WSDL supports literal encoding only - ${ item.get_use } found"; END %] 'use' => '[% item.get_use %]', namespace => '[% item.get_namespace %]', encodingStyle => '[% item.get_encodingStyle %]', parts => [qw( [% part_class %] )],SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD004075500017500001750000000000001361135364200226365ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Type.tt010064400017500001750000000003441237511274000242030ustar00scottscott[%- indent = ' '; IF type.isa('SOAP::WSDL::XSD::ComplexType'); INCLUDE complexType/POD/structure.tt(complexType = type); ELSE; INCLUDE simpleType/POD/structure.tt(simpleType = type); END; indent.replace('\s{2}$',''); %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt010064400017500001750000000014041361134503300255500ustar00scottscottMethod synopsis is displayed with hash refs as parameters. The commented class names in the method's parameters denote that objects of the corresponding class can be passed instead of the marked hash ref. You may pass any combination of objects, hash and list refs to these methods, as long as you meet the structure. List items (i.e. multiple occurrences) are not displayed in the synopsis. You may generally pass a list ref of hash refs (or objects) instead of a hash ref - this may result in invalid XML if used improperly, though. Note that SOAP::WSDL always expects list references at maximum depth position. XML attributes are not displayed in this synopsis and cannot be set using hash refs. See the respective class' documentation for additional information. SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Element.tt010064400017500001750000000007051237511274000246540ustar00scottscott [% INDENT; %][% element.get_name %] => [%- IF (element.get_ref); element = element.get_ref(); END; IF (type_name = element.get_type); INCLUDE Interface/POD/Type.tt(type = definitions.first_types.find_type( element.expand(type_name) ) ); ELSIF (type = element.first_complexType); INCLUDE Interface/POD/Type.tt(type = type ); ELSIF (type = element.first_simpleType); INCLUDE Interface/POD/Type.tt(type = type ); END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Operation.tt010064400017500001750000000017261237511274000252270ustar00scottscott[%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% head3 = BLOCK %]=head3[% END -%] [% head3 %] [% operation.get_name %] [% type = definitions.find_portType( binding.expand( binding.get_type ) ); port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name ); port_op.get_documentation(); # for now we only document the first response part - document/literal # doesn't allow more. response_name = port_op.first_output.get_message(); response_part = definitions.find_message( port_op.first_output.expand( response_name ) ).get_part(); response_body_element = definitions.first_types.find_element( response_part.0.expand( response_part.0.get_element ) ); response_body_class = XSD.create_xsd_name(response_body_element); %] Returns a L<[% response_body_class %]|[% response_body_class %]> object. $response = $interface->[% operation.get_name %]([% INCLUDE Interface/POD/Message.tt %] ); SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Message.tt010064400017500001750000000003761237511274000246530ustar00scottscott[% message_name = port_op.first_input.get_message(); # message_name; part_from = definitions.find_message( port_op.first_input.expand( message_name ) ).get_part; FOREACH part = part_from; INCLUDE Interface/POD/Part.tt(part = part); END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Part.tt010064400017500001750000000005031237511274000241650ustar00scottscott[% element = definitions.first_types.find_element( part.expand( part.get_element ) ); #element.get_name(); #element; #STOP; type = element.first_complexType || element.first_simpleType || definitions.first_types.find_type( element.expand( element.get_type ) ); INCLUDE Interface/POD/Type.tt;%], SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt010064400017500001750000000056541237511274000235460ustar00scottscott[% RETURN IF NOT item; type = definitions.find_portType( binding.expand( binding.get_type ) ); port_op = type.find_operation( type.get_targetNamespace, operation.get_name ); message = definitions.find_message( port_op.first_input.expand( port_op.first_input.get_message ) ); part_from = message.get_part; PERL %] my $item = $stash->{ item }; my $def = $stash->{ definitions }; my $part_from = $stash->{ message }->get_part(); my @body_part_from = split m{\s}, $item->get_parts; my @parts; if (@body_part_from) { @parts = map { my $part = $_; (grep { # my ($ns, $lname) = $def->expand( $_ ); ($_ eq $part->get_name) } @body_part_from ) ? do { my $name; ($name = $part->get_element) ? do { my $element = $def->first_types->find_element($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : ($name = $part->get_type) ? do { my $element = $def->first_types->find_type($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : die "input must have either type or element" } : () } @{ $part_from }; } else { @parts = map { my $part = $_; my $name; ($name = $part->get_element) ? do { my $element = $def->first_types->find_element($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : ($name = $part->get_type) ? do { my $element = $def->first_types->find_type($part->expand($name)); my $resolver = $context->plugin('XSD'); $resolver->create_xsd_name($element); } : die "input must have either type or element"; } @{ $part_from }; } warn "Multiple parts detected in message " . $stash->{ message }->get_name() . ".\n", "WS-I BP demands 0 to 1 parts in message body\n" if (@parts > 1); $stash->{ parts } = \@parts; [% END %] [% IF item.get_use != 'literal'; THROW NOT_SUPPORTED "Body: SOAP::WSDL supports literal encoding only - ${ item.get_use } found"; END %] 'use' => '[% item.get_use %]', namespace => '[% item.get_namespace %]', encodingStyle => '[% item.get_encodingStyle %]', parts => [qw( [% parts.join(' ') %] )],SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt010064400017500001750000000017011237511274000245760ustar00scottscottsub [% operation.get_name %] { my ($self, $body, $header) = @_; die "[% operation.get_name %] must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ operation => '[% operation.get_name %]', soap_action => '[% operation.first_operation.get_soapAction %]', style => [% style = operation.first_operation.get_style || binding.get_style; IF style != "document"; THROW NOT_SUPPORTED "SOAP::WSDL supports document encoding only - $style found"; END; -%] '[% style %]', body => { [% INCLUDE Interface/Body.tt( item = operation.first_input.first_body ); %] }, header => { [% INCLUDE Interface/Header.tt( item = operation.first_input.first_header ); %] }, headerfault => { [% INCLUDE Interface/Header.tt( item = operation.first_input.first_headerfault ); %] } }, $body, $header); } SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/element.tt010064400017500001750000000060451237511274000223750ustar00scottscott[% USE XSD(context) %] package [% XSD.create_xsd_name(element) %]; use strict; use warnings; { # BLOCK to scope variables sub get_xmlns { '[% element.get_targetNamespace %]' } __PACKAGE__->__set_name('[% element.get_name %]'); __PACKAGE__->__set_nillable([% IF (element.get_nillable); IF (element.get_nillable != 'false'); %]1[% ELSE %]0[% END; END; %]); __PACKAGE__->__set_minOccurs([% element.get_minOccurs %]); __PACKAGE__->__set_maxOccurs([% element.get_maxOccurs %]); __PACKAGE__->__set_ref([% IF element.get_ref; %]'[% element.get_ref %]'[% END %]); [%- IF (type_name = element.get_type); -%] use base qw( SOAP::WSDL::XSD::Typelib::Element [% type = definitions.get_types.0.find_type(element.expand(type_name)); XSD.create_xsd_name(type) %] ); } [%- ELSIF (ref = element.get_ref); ref_from = ref.split(':'); -%] # element ref="[% ref %]" use base qw( [% ref_element = definitions.get_types.0.find_element(element.expand(ref)); XSD.create_xsd_name( ref_element ); %] ); } [%- ELSIF (simpleType = element.first_simpleType) %] # atomic simpleType: set_[% XSD.perl_var_name(XSD.element_name(child_element)) %]($data); $element->get_[% XSD.perl_var_name(XSD.element_name(child_element)) %](); [% IF (XSD.perl_var_name(XSD.element_name(child_element)) == child_element.get_name); %] [% ELSE %] Note: The name of this property has been altered, because it didn't match perl's notion of variable/subroutine names. The altered name is used in perl code only, XML output uses the original name: [% child_element.get_name %] [% END %] [% END; %] =back [% END; END; -%] [% head1 %] METHODS [% head2 %] new my $element = [% XSD.create_xsd_name(element) %]->new($data); Constructor. The following data structure may be passed to new(): [% indent = ' '; INCLUDE element/POD/structure.tt; %] [% head1 %] AUTHOR Generated by SOAP::WSDL =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt010064400017500001750000000036151237511274000227470ustar00scottscott[% USE XSD(context) %] package [% XSD.create_xsd_name(attribute) %]; use strict; use warnings; { # BLOCK to scope variables sub get_xmlns { '[% attribute.get_targetNamespace %]' } __PACKAGE__->__set_name('[% attribute.get_name %]'); __PACKAGE__->__set_ref([% IF attribute.get_ref; %]'[% attribute.get_ref %]'[% END %]); [%- IF (type_name = attribute.get_type); -%] use base qw( SOAP::WSDL::XSD::Typelib::Attribute [% type = definitions.get_types.0.find_type(attribute.expand(type_name)); IF ! type; THROW NOT_FOUND "type " _ type_name _ " not found in attribute " _ attribute.get_name; END; XSD.create_xsd_name(type) %] ); } [%- ELSIF (ref = attribute.get_ref); ref_from = ref.split(':'); -%] # attribute ref="[% ref %]" use base qw( [% ref_element = definitions.get_types.0.find_attribute(attribute.expand(ref)); XSD.create_xsd_name( ref_element ); %] ); } [%- ELSIF (simpleType = attribute.first_simpleType) %] # atomic simpleType: new($data); Constructor. The following data structure may be passed to new(): { value => $value } [% head1 %] AUTHOR Generated by SOAP::WSDL =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server004075500017500001750000000000001361135364100215615ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD004075500017500001750000000000001361135364200222045ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt010064400017500001750000000005671237511274000242350ustar00scottscott[% element = definitions.first_types.find_element( part.expand( part.get_element ) ); #element.get_name(); #element; #STOP; -%] [% XSD.create_xsd_name(element) %]->new([% type = element.first_complexType || element.first_simpleType || definitions.first_types.find_type( element.expand( element.get_type ) ); INCLUDE Interface/POD/Type.tt; %] ); SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/method_info.tt010064400017500001750000000002131237511274000251160ustar00scottscottYour dispatch_to class has to implement the following methods: The examples below serve as copy-and-paste prototypes to use in your class.SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Message.tt010064400017500001750000000004001237511274000242050ustar00scottscott[% message_name = port_op.first_output.get_message(); # message_name; part_from = definitions.find_message( port_op.first_output.expand( message_name ) ).get_part; FOREACH part = part_from; INCLUDE Server/POD/OutPart.tt(part = part); END; %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Operation.tt010064400017500001750000000033061237511274000245710ustar00scottscott[%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% head3 = BLOCK %]=head3[% END -%] [% head3 %] [% operation.get_name %] [% type = definitions.find_portType( binding.expand( binding.get_type ) ); port_op = ''; FOREACH port_op = type.get_operation(); IF (port_op.get_name == operation.get_name); LAST; END; END; input_message_name = port_op.first_input.get_message(); output_message_name = port_op.first_output.get_message(); input_message = definitions.find_message(port_op.first_input.expand(input_message_name)); output_message = definitions.find_message(port_op.first_output.expand(output_message_name)); input_parts = input_message.get_part(); output_parts = output_message.get_part(); # port_op.get_documentation %] sub [% operation.get_name %] { my ($self, $body, $header) = @_; [% IF (input_parts.size() > 1); -%] # body is a list ref of the following objects: # [ # sorry - POD support not implemented yet # ] [% ELSE; input_element = definitions.first_types.find_element(input_parts.0.expand(input_parts.0.get_element)); IF (input_element); class = XSD.create_xsd_name( input_element ); ELSE; input_type = definitions.first_types.find_type(input_parts.0.expand(input_parts.0.get_type)); class = XSD.create_xsd_name( input_type ); END; -%] # body is a [% class %] object [%- END; %] # header is a ??? object - sorry, POD support not implemented yet # do something with body and header... return [% INCLUDE Server/POD/Message.tt %] } SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/element004075500017500001750000000000001361135364100217445ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/element/POD004075500017500001750000000000001361135364200223675ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt010064400017500001750000000004651237511274000254520ustar00scottscott[% IF (type = element.get_type); ELSIF (simpleType = element.get_simpleType) %] This XML element type class has a atomic simpleType as it's base: [% INCLUDE simpleType/POD/contentModel.tt(simpleType = simpleType); ELSIF (simpleType = element.get_complexType); ELSIF (ref_element = element.get_ref); END %]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/element/POD/structure.tt010064400017500001750000000021541237511274000250540ustar00scottscott[%- IF (name = element.get_type); type_name = element.expand(name); IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%] $some_value, # [% type_name.1 %] [%- RETURN; ELSIF (type = definitions.first_types.find_type( type_name )); IF (type.isa('SOAP::WSDL::XSD::ComplexType') ); INCLUDE complexType/POD/structure.tt(complexType = type); RETURN; ELSE; INCLUDE simpleType/POD/structure.tt(simpleType = type); END; RETURN; END; THROW NOT_FOUND, "no type found for {${type_name.0}}${type_name.1}"; ELSIF (ref = element.get_ref); ref_element = definitions.first_types.find_element( element.expand( ref ) ); INCLUDE element/POD/structure.tt(element = ref_element); RETURN; ELSIF (type = element.first_simpleType); INCLUDE simpleType/POD/structure.tt(simpleType = type); RETURN; ELSIF (type = element.first_complexType); INCLUDE complexType/POD/structure.tt(complexType = type); ELSE; THROW NOT_FOUND, "no type found for ${element.get_name}"; %] NO TYPE FOUND FOR ELEMENT [% element.get_name %] [% END -%]SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/POD004075500017500001750000000000001361135364100207355ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt010064400017500001750000000000571237511274000235350ustar00scottscott[% node.get_annotation.0.get_documentation %] SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt010064400017500001750000000042331237511274000226410ustar00scottscott[% USE XSD -%] [% interface_name = XSD.create_interface_name(service, port) -%] package [% interface_name %]; use strict; use warnings; use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before require [% XSD.create_typemap_name(service) %] if not [% XSD.create_typemap_name(service) %]->can('get_class'); sub START { $_[0]->set_proxy('[% port.first_address.get_location %]') if not $_[2]->{proxy}; $_[0]->set_class_resolver('[% XSD.create_typemap_name(service) %]') if not $_[2]->{class_resolver}; $_[0]->set_prefix($_[2]->{use_prefix}) if exists $_[2]->{use_prefix}; } [% binding = definitions.find_binding( port.expand( port.get_binding ) ); FOREACH operation = binding.get_operation; %][% INCLUDE Interface/Operation.tt %] [% END; %] 1; [% IF NO_POD; STOP; END %] __END__ [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% pod = BLOCK %]=pod[% END -%] [% head1 = BLOCK %]=head1[% END -%] [% head2 = BLOCK %]=head2[% END -%] [% head3 = BLOCK %]=head3[% END -%] [% pod %] [% head1 %] NAME [% interface_name %] - SOAP Interface for the [% service.get_name %] Web Service [% head1 %] SYNOPSIS use [% interface_name %]; my $interface = [% interface_name %]->new(); my $response; [% FOREACH operation = binding.get_operation; %] $response = $interface->[% operation.get_name %](); [% END %] [% head1 %] DESCRIPTION SOAP Interface for the [% service.get_name %] web service located at [% port.first_address.get_location %]. [% head1 %] SERVICE [% service.get_name %] [% service.get_documentation %] [% head2 %] Port [% port.get_name %] [% port.get_documentation %] [% head1 %] METHODS [% head2 %] General methods [% head3 %] new Constructor. All arguments are forwarded to L. [% head2 %] SOAP Service methods [% INCLUDE Interface/POD/method_info.tt %] [% FOREACH operation = binding.get_operation; %][% INCLUDE Interface/POD/Operation.tt %] [% END %] [% head1 %] AUTHOR Generated by SOAP::WSDL on [% PERL %]print scalar localtime() [% END %] =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt010064400017500001750000000036531237511274000232570ustar00scottscott[% USE XSD; USE Dumper -%] package [% XSD.create_xsd_name(complexType) %]; use strict; use warnings; [%# # Don't include any perl source for this package below this line - there # may be sub-packages... #-%] __PACKAGE__->_set_element_form_qualified([%- IF complexType.schema.get_elementFormDefault == 'qualified' -%]1[% ELSE %]0[% END %]); sub get_xmlns { '[% complexType.get_targetNamespace %]' }; [% INCLUDE complexType/contentModel.tt %] 1; [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% pod = BLOCK %]=pod[% END -%] [% head1 = BLOCK %]=head1[% END -%] [% head2 = BLOCK %]=head2[% END -%] [% head3 = BLOCK %]=head3[% END -%] [% pod %] [% head1 %] NAME [% XSD.create_xsd_name(complexType) %] [% head1 %] DESCRIPTION Perl data type class for the XML Schema defined complexType [% complexType.get_name %] from the namespace [% complexType.get_targetNamespace %]. [% INCLUDE POD/annotation.tt(node = complexType) %] [% IF (complexType.get_element); %] [% head2 %] PROPERTIES The following properties may be accessed using get_PROPERTY / set_PROPERTY methods: =over [% FOREACH element = complexType.get_element -%] =item * [% XSD.perl_var_name(XSD.element_name(element)) %] [% IF (XSD.perl_var_name(XSD.element_name(element)) == element.get_name); %] [% ELSE %] Note: The name of this property has been altered, because it didn't match perl's notion of variable/subroutine names. The altered name is used in perl code only, XML output uses the original name: [% element.get_name %] [% END %] [% IF element.get_annotation.get_documentation; %] [% element.get_annotation.get_documentation %] [% END -%] [% END %] =back [% END -%] [% head1 %] METHODS [% head2 %] new Constructor. The following data structure may be passed to new(): [% indent = ' '; INCLUDE complexType/POD/structure.tt %] [% INCLUDE complexType/POD/attributeSet.tt %] [% head1 %] AUTHOR Generated by SOAP::WSDL =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt010064400017500001750000000012271237511274000223600ustar00scottscott[% USE XSD %] package [% XSD.create_typemap_name(service) %]; use strict; use warnings; our [% USE Dumper(varname = 'typemap_'); Dumper.dump( typemap ) %]; sub get_class { my $name = join '/', @{ $_[1] }; return $typemap_1->{ $name }; } sub get_typemap { return $typemap_1; } 1; __END__ __END__ [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] [% pod = BLOCK %]=pod[% END -%] [% head1 = BLOCK %]=head1[% END -%] [% pod %] [% head1 %] NAME [% XSD.create_typemap_name(service) %] - typemap for [% service.get_name %] [% head1 %] DESCRIPTION Typemap created by SOAP::WSDL for map-based SOAP message parsers. =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/XSD.pm010064400017500001750000000237211361135215300207270ustar00scottscottpackage SOAP::WSDL::Generator::Template::XSD; use strict; use warnings; use Template 2.18; use Class::Std::Fast::Storable; use File::Basename; use File::Spec; our $VERSION = 3.004; use SOAP::WSDL::Generator::Visitor::Typemap; use SOAP::WSDL::Generator::Template::Plugin::XSD; use base qw(SOAP::WSDL::Generator::Template); my %output_of :ATTR(:name :default<()>); my %typemap_of :ATTR(:name :default<({})>); my %silent_of :ATTR(:name :default<0>); sub BUILD { my ($self, $ident, $arg_ref) = @_; $self->set_EVAL_PERL(1); $self->set_RECURSION(1); $self->set_INCLUDE_PATH( exists $arg_ref->{INCLUDE_PATH} ? $arg_ref->{INCLUDE_PATH} : do { # ignore uninitialized warnings - File::Spec warns about # uninitialized values, probably because we have no filename local $SIG{__WARN__} = sub { return if ($_[0]=~m{\buninitialized\b}); CORE::warn @_; }; # makeup path for the OS we're running on my ($volume, $dir, $file) = File::Spec->splitpath( File::Spec->rel2abs( dirname __FILE__ ) ); $dir = File::Spec->catdir($dir, $file, 'XSD'); # return path put together... my $path = File::Spec->catpath( $volume, $dir , q{}); # Fixup path for windows - / works fine, \ does # not... if ( eval { &Win32::BuildNumber } ) { $path =~s{\\}{/}g; } $path; } ); } # construct object on call to allow late binding of prefix_resolver class # and namespace maps (not used yet) sub get_name_resolver { my $self = shift; return SOAP::WSDL::Generator::Template::Plugin::XSD->new({ prefix_resolver => $self->get_prefix_resolver_class()->new({ namespace_prefix_map => { 'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin', }, namespace_map => { }, prefix => { attribute => $self->get_attribute_prefix, interface => $self->get_interface_prefix, element => $self->get_element_prefix, server => $self->get_server_prefix, type => $self->get_type_prefix, typemap => $self->get_typemap_prefix, } }) }); } sub generate { my $self = shift; my $opt = shift; $self->generate_typelib( $opt ); $self->generate_typemap( $opt ); } sub generate_typelib { my ($self, $arg_ref) = @_; my @schema = exists $arg_ref->{ schema } ? @{ $arg_ref->{schema} } : @{ $self->get_definitions()->first_types()->get_schema() }; for my $type (map { @{ $_->get_type() } , @{ $_->get_element() }, @{ $_->get_attribute() } } @schema[1..$#schema] ) { $type->_accept( $self ); } return; } sub _generate_interface { my $self = shift; my $arg_ref = shift; my $template_name = delete $arg_ref->{ template_name }; my $name_method = delete $arg_ref->{ name_method }; for my $service (@{ $self->get_definitions->get_service }) { for my $port (@{ $service->get_port() }) { # Skip ports without (known) address next if not $port->first_address; next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address'); my $port_name = $port->get_name; $port_name =~s{ \A .+\. }{}xms; my $output = $arg_ref->{ output } ? $arg_ref->{ output } : $self->_generate_filename( $self->get_name_resolver()->can($name_method)->( $self->get_name_resolver(), $service, $port, )); print "Creating interface class $output\n" if not $silent_of{ident $self}; $self->_process($template_name, { service => $service, port => $port, NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 , }, $output, binmode => ':utf8'); } } } sub generate_server { my ($self, $arg_ref) = @_; $arg_ref->{ template_name } = 'Server.tt'; $arg_ref->{ name_method } = 'create_server_name'; $self->_generate_interface($arg_ref); } sub generate_client { my ($self, $arg_ref) = @_; $arg_ref->{ template_name } = 'Interface.tt'; $arg_ref->{ name_method } = 'create_interface_name'; $self->_generate_interface($arg_ref); } sub generate_interface; *generate_interface = \&generate_client; sub generate_typemap { my ($self, $arg_ref) = @_; my $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new({ type_prefix => $self->get_type_prefix(), element_prefix => $self->get_element_prefix(), definitions => $self->get_definitions(), typemap => { 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', %{ $typemap_of{ident $self }}, }, resolver => $self->get_name_resolver(), }); use SOAP::WSDL::Generator::Iterator::WSDL11; my $iterator = SOAP::WSDL::Generator::Iterator::WSDL11->new({ definitions => $self->get_definitions }); for my $service (@{ $self->get_definitions->get_service }) { $iterator->init({ node => $service }); while (my $node = $iterator->get_next()) { $node->_accept( $visitor ); } my $output = $arg_ref->{ output } ? $arg_ref->{ output } : $self->_generate_filename( $self->get_name_resolver()->create_typemap_name($service) ); print "Creating typemap class $output\n" if not $silent_of{ident $self}; $self->_process('Typemap.tt', { service => $service, typemap => $visitor->get_typemap(), NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 , }, $output); } } sub _generate_filename :PRIVATE { my ($self, $name) = @_; $name =~s{ \. }{::}xmsg; $name =~s{ \- }{_}xmsg; $name =~s{ :: }{/}xmsg; return "$name.pm"; } sub visit_XSD_Attribute { my ($self, $attribute) = @_; my $output = defined $output_of{ ident $self } ? $output_of{ ident $self } : $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($attribute) ); $self->_process('attribute.tt', { attribute => $attribute } , $output); } sub visit_XSD_Element { my ($self, $element) = @_; my $output = defined $output_of{ ident $self } ? $output_of{ ident $self } : $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($element) ); warn "Creating element class $output \n" if not $silent_of{ ident $self}; $self->_process('element.tt', { element => $element } , $output); } sub visit_XSD_SimpleType { my ($self, $type) = @_; my $output = defined $output_of{ ident $self } ? $output_of{ ident $self } : $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($type) ); warn "Creating simpleType class $output \n" if not $silent_of{ ident $self}; $self->_process('simpleType.tt', { simpleType => $type } , $output); } sub visit_XSD_ComplexType { my ($self, $type) = @_; my $output = defined $output_of{ ident $self } ? $output_of{ ident $self } : $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($type) ); warn "Creating complexType class $output \n" if not $silent_of{ ident $self}; $self->_process('complexType.tt', { complexType => $type } , $output); } 1; =pod =head1 NAME SOAP::WSDL::Generator::Template::XSD - XSD code generator =head1 DESCRIPTION SOAP::WSDL's XSD code generator =head1 SYNOPSIS See L for an example on how to use this class. =head1 METHODS =head2 new Constructor. Options (Options can also be set via set_OPTION methods): =over =item * silent Suppress warnings about what's being generated =back =head2 generate Shortcut for calling L and L =head2 generate_client Generates a client interface =head2 generate_server Generates a server class =head2 generate_typelib Generates type and element classes =head2 generate_typemap Generate a typemap class required by SOAP::WSDL's MessageParser =head2 generate_interface (Deprecated) alias for generate_client =head2 get_name_resolver Returns a name resolver template plugin =head2 visit_XSD_Attribute Visitor method for SOAP::WSDL::XSD::Attribute. Should be factored out into visitor class. =head2 visit_XSD_ComplexType Visitor method for SOAP::WSDL::XSD::ComplexType. Should be factored out into visitor class. =head2 visit_XSD_Element Visitor method for SOAP::WSDL::XSD::Element. Should be factored out into visitor class. =head2 visit_XSD_SimpleType Visitor method for SOAP::WSDL::XSD::SimpleType. Should be factored out into visitor class. =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2008, 2009 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: WSDLParser.pm 770 2009-01-24 22:55:54Z kutterma $ $LastChangedDate: 2009-01-24 23:55:54 +0100 (Sa, 24 Jan 2009) $ $LastChangedRevision: 770 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/Plugin004075500017500001750000000000001361135364200211145ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm010064400017500001750000000140741361135215300221660ustar00scottscottpackage SOAP::WSDL::Generator::Template::Plugin::XSD; use strict; use warnings; use Carp qw(confess); use Class::Std::Fast::Storable constructor => 'none'; use Scalar::Util qw(blessed); our $VERSION = 3.004; my %namespace_prefix_map_of :ATTR(:name :default<{}>); my %namespace_map_of :ATTR(:name :default<{}>); my %prefix_of :ATTR(:name :default<()>); my %prefix_resolver_of :ATTR(:name :default<()>); my %definitions_of :ATTR(:name :default<()>); # create a singleton sub load { # called as MyPlugin->load($context) my ($class, $context, @arg_from) = @_; my $stash = $context->stash(); my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class; $self->set_prefix_resolver( $stash->{ context }->{ prefix_resolver }); $self->set_definitions( $stash->{ definitions }); return $self; # returns 'MyPlugin' } sub new { return shift if ref $_[0]; my ($class, $arg_ref) = @_; my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class; $self->set_prefix_resolver( $arg_ref->{ prefix_resolver }); $self->set_definitions( $arg_ref->{ definitions }); return $self; # returns 'MyPlugin' } sub _get_prefix { my ($self, $type, $node) = @_; my $namespace = defined ($node) ? ref($node) ? $node->get_targetNamespace() : $node : undef; return $self->get_prefix_resolver()->resolve_prefix( $type, $namespace, ref($node) ? $node : undef ); } sub create_xsd_name { my ($self, $node) = @_; confess "no node $node" if not defined($node) or $node eq ""; my $name = $self->_resolve_prefix($node) #. '::' . $node->get_name(); return $self->perl_name( $name ); } sub create_typemap_name { my ($self, $node) = @_; my $name = $self->_get_prefix('typemap') #. '::' . $node->get_name(); return $self->perl_name( $name ); } sub create_server_name { my ($self, $server, $port) = @_; my $port_name = $port->get_name(); $port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x; my $name = join( q{}, $self->_get_prefix('server', $server), join( '::', $server->get_name(), $port_name) ); return $self->perl_name( $name ); } sub create_interface_name { my ($self, $server, $port) = @_; my $port_name = $port->get_name(); $port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x; my $name = join( q{}, $self->_get_prefix('interface', $server), join( '::', $server->get_name(), $port_name ) ); return $self->perl_name( $name ); } sub _resolve_prefix { my ($self, $node) = @_; if ($node->isa('SOAP::WSDL::XSD::Builtin')) { return $self->_get_prefix('type', $node) } if ( $node->isa('SOAP::WSDL::XSD::SimpleType') or $node->isa('SOAP::WSDL::XSD::ComplexType') ) { return $self->_get_prefix('type', $node); } if ( $node->isa('SOAP::WSDL::XSD::Element') ) { return $self->_get_prefix('element', $node); } if ( $node->isa('SOAP::WSDL::XSD::Attribute') ) { return $self->_get_prefix('attribute', $node); } } sub perl_name { my $self = shift; my $name = shift; $name =~s{\-}{_}xmsg; $name =~s{\.}{::}xmsg; return $name; } sub perl_var_name { my $self = shift; my $name = shift; $name =~s{\-}{_}xmsg; $name =~s{\.}{__}xmsg; return $name; } sub create_subpackage_name { my $self = shift; my $arg_ref = shift; my $type = ref $arg_ref eq 'HASH' ? $arg_ref->{ value } : $arg_ref; my @name_from = $type->get_name() || (); ; # search for top node in tree (the one directly below the Schema) my $parent = $type; my $top_node = $parent; if (! $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema') ) { NAMES: while ($parent = $parent->get_parent()) { $top_node = $parent; last NAMES if $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema'); # skip empty names - atomic types have no name... unshift @name_from, $parent->get_name() if $parent->get_name(); } } # create name for top node die "No top node found" if not defined $top_node; my $top_node_name = $self->create_xsd_name($top_node); my $package_name = join('::_', $top_node_name , (@name_from) ? join('::', @name_from) : () ); # replace dots by :: in name - subpackage names may include dots, too $package_name =~s{\.}{::}xg; return $package_name; } sub create_xmlattr_name { return join '::', shift->create_subpackage_name(shift), 'XmlAttr'; } sub element_name { my $self = shift; my $element = shift; confess "no element object" unless blessed $element; my $name = $element->get_name(); if (! $name) { while (my $ref = $element->get_ref()) { $element = $self->get_definitions()->first_types() ->find_element($element->expand( $ref ) ); $name = $element->get_name(); last if ($name); } } return $name; } 1; =pod =head1 NAME SOAP::WSDL::Generator::Template::Plugin::XSD - Template plugin for the XSD generator =head1 METHODS =head2 perl_name XSD.perl_name(element.get_name); Converts a XML name into a valid perl name (valid for subroutines, variables or the like). perl_name takes a crude approach by just replacing . and - (dot and dash) with a underscore. This may or may not be sufficient, and may or may not provoke collisions in your XML names. =head1 LICENSE AND COPYRIGHT Copyright 2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 564 $ $LastChangedBy: kutterma $ $Id: ComplexType.pm 564 2008-02-23 13:31:39Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Iterator004075500017500001750000000000001361135364100176735ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm010064400017500001750000000172141361135215200212210ustar00scottscottpackage SOAP::WSDL::Generator::Iterator::WSDL11; use strict; use warnings; use Class::Std::Fast; our $VERSION = 3.004; my %definitions_of :ATTR(:name :default<[]>); my %nodes_of :ATTR(:name :default<[]>); # memoization attributes my %portType_of :ATTR(); my %types_of :ATTR(); my %METHOD_OF = ( 'SOAP::WSDL::Definitions' => 'get_service', 'SOAP::WSDL::Service' => 'get_port', 'SOAP::WSDL::Port' => sub { my ($self, $node) = @_; return if ! $node->first_address() or ! $node->first_address()->isa('SOAP::WSDL::SOAP::Address'); return [ $self->get_definitions() ->find_binding( $node->expand( $node->get_binding() ) ) || () ]; }, 'SOAP::WSDL::Binding' => sub { my ($self, $node) = @_; # remember referenced portType $portType_of{ ident $self } = $self->get_definitions() ->find_portType( $node->expand( $node->get_type ) ) or return []; return $node->get_operation(); }, 'SOAP::WSDL::Operation' => sub { my ($self, $node) = @_; my $name = $node->get_name(); # get the equally named operation from the portType my ($op) = grep { $_->get_name() eq $name } @{ $portType_of{ ident $self }->get_operation() } or return []; return [ @{ $op->get_input }, @{ $op->get_output }, @{ $op->get_fault } ] }, 'SOAP::WSDL::OpMessage' => sub { my ($self, $node) = @_; return if ( ref $node->get_parent() eq 'SOAP::WSDL::Binding' ); # we're in binding # TODO maybe allow more messages && overloading by specifying name return [ $self->get_definitions()->find_message( $node->expand( $node->get_message() ) ) || () ]; }, 'SOAP::WSDL::Message' => 'get_part', 'SOAP::WSDL::Part' => sub { my ($self, $node) = @_; my $ident = ident $self; my $types = $types_of{ $ident } = $definitions_of{ $ident }->get_types()->[0] or return []; return [ # If we have a type, this type is to be used in document/literal # as global type. However this is forbidden, at least by WS-I. # We should store the style/encoding somewhere, and regard it. # TODO: auto-generate element for RPC bindings $node->get_type() ? do { die "unsupported global type <" . $node->get_type . "> found in part <". $node->get_name() . ">\n" . "Looks like a rpc/literal WSDL, which is not supported by SOAP::WSDL\n"; ## use this once we can auto-generate an element for RPC bindings # $types->find_type( $node->expand($node->get_type) ) } : (), $node->get_element() ? $types->find_element( $node->expand($node->get_element) ) : (), ]; }, ); sub init { my ($self, $arg_of) = @_; my $ident = ident $self; undef $portType_of{ $ident }; undef $types_of{ $ident }; $nodes_of{ $ident } = [ exists($arg_of->{ node }) ? $arg_of->{ node } : $definitions_of{ ident $self } ]; } sub get_next { my $self = shift; my $ident = ident $self; my $node = shift @{ $nodes_of{ $ident }}; return if ! defined $node; unshift @{ $nodes_of{ $ident }}, @{ $self->get_nextNodes( $node ) || [] }; return $node; } sub get_nextNodes { my ($self, $node) = @_; my $method = $METHOD_OF{ ref $node } or return []; return (ref($method) eq 'CODE') ? $method->( $self, $node ) : $node->can($method)->( $node ); } 1; __END__ =pod =head1 NAME SOAP::WSDL::Generator::Iterator::WSDL11 - WSDL 1.1 Iterator =head1 SYNOPSIS my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new({ definitions => $wsdl }); $iter->init(); while (my $node = $iter->get_next()) { # do something with node - possibly call _accept with a visitor on it... } =head1 DESCRIPTION Iterator for walking a WSDL 1.1 definition. The iterator performs a depth-first search along the following path: service port binding operation input/output/fault of operation in portType message part type/element in XML schema If you wonder about this path: This is how to look up which XML Schema element is associated with a operation from a service/port. =head2 Example The nodes are returned in the order denoted in the following example: You should not rely too much on this order - it may change. Even though the current order will probably remain, the nodes currently skipped might be returned somewhere along the path. =head1 LICENSE AND COPYRIGHT Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 239 $ $LastChangedBy: kutterma $ $Id: Client.pm 239 2007-09-11 09:45:42Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Visitor004075500017500001750000000000001361135364100175415ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm010064400017500001750000000154541361135215300216000ustar00scottscottpackage SOAP::WSDL::Generator::Visitor::Typemap; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Generator::Visitor); our $VERSION = 3.004; my %path_of :ATTR(:name :default<[]>); my %typemap_of :ATTR(:name :default<()>); my %resolver_of :ATTR(:name :default<()>); sub START { my ($self, $ident, $arg_ref) = @_; $resolver_of { $ident } = $arg_ref->{ resolver }; } sub set_typemap_entry { my ($self, $value) = @_; # warn join( q{/}, @{ $path_of{ ident $self } }) . " => $value"; $typemap_of{ ident $self }->{ join( q{/}, @{ $path_of{ ident $self } } ) } = $value; } sub add_element_path { my ($self, $element) = @_; # Swapping out this lines against the ones below generates # a namespace-sensitive typemap. # Well almost: Class names are not constructed in a namespace-sensitive # manner, yet - there should be some facility to allow binding a (perl) # prefix to a namespace... if (my $ref = $element->get_ref() ) { $element = $self->get_definitions()->first_types()->find_element( $element->expand($ref) ); } my $name = $element->get_name(); push @{ $path_of{ ident $self } }, $name; } sub process_referenced_type { my ( $self, $ns, $localname ) = @_; my $ident = ident $self; # get type's class name # Caveat: visits type if it's a referenced type from the # a ? b : c operation. my ($type, $typeclass); $type = $self->get_definitions()->first_types()->find_type( $ns, $localname ); $typeclass = $self->get_resolver()->create_xsd_name($type); # set before to allow it to be used from inside _accept $self->set_typemap_entry($typeclass); $type->_accept($self) if ($ns ne 'http://www.w3.org/2001/XMLSchema'); # set afterwards again (just to be sure...) $self->set_typemap_entry($typeclass); return $self; } sub visit_XSD_Element { my ( $self, $ident, $element ) = ( $_[0], ident $_[0], $_[1] ); # warn "simpleType " . $element->get_name(); my @path = @{ $path_of{ ${ $self } } }; my $path = join '/', @path; my $parent = $typemap_of{ ${ $self } }->{ $path }; # step down in tree $self->add_element_path( $element ); # now call all possible variants. # They all just return if no argument is given, # and return $self on success. SWITCH: { my $name = $element->get_name(); if ($element->get_type) { $self->process_referenced_type( $element->expand( $element->get_type() ) ); last SWITCH; } # atomic simpleType typemap rule: # if we have a parent, use parent's sub-package. # if not, use element package. if ($element->get_simpleType()) { # warn "simpleType " . $element->get_name(); my @path = @{ $path_of{ ${ $self } } }; my $typeclass = $self->get_resolver()->create_subpackage_name($element); $self->set_typemap_entry($typeclass); $typeclass =~s{\.}{::}g; $typeclass =~s{\-}{_}g; last SWITCH; } # for atomic and complex types , and ref elements my $typeclass = $self->get_resolver()->create_subpackage_name($element); $self->set_typemap_entry($typeclass); if (my $complexType = $element->first_complexType()) { $complexType->_accept($self); last SWITCH; } # element ref handling if (my $ref = $element->get_ref()) { $element = $self->get_definitions()->first_types()->find_element( $element->expand($ref) ); # we added a path too much - we should add the path of this # element instead. pop @{ $path_of{$ident} }; $element->_accept($self); # and we must not pop it off now - thus, just return return; } die "Neither type nor ref in element >". $element->get_name ."<. Don't know what to do." }; # Safety measure. If someone defines a top-level element with # a normal (not atomic) type, we just override it here if (not defined($parent)) { # for atomic and complex types , and ref elements my $typeclass = $self->get_resolver()->create_xsd_name($element); $self->set_typemap_entry($typeclass); } # step up in hierarchy pop @{ $path_of{$ident} }; } sub visit_XSD_ComplexType { my ($self, $ident, $type) = ($_[0], ident $_[0], $_[1] ); my $variety = $type->get_variety(); my $derivation = $type->get_derivation(); my $content_model = $type->get_contentModel; return if not $variety; # empty complexType return if ($content_model eq 'simpleContent'); if ( grep { $_ eq $variety} qw(all sequence choice) ) { # visit child elements for (@{ $type->get_element() || [] }) { $_->_accept( $self ); } } # Only continue for derived types # Saves a uninitialized warning. return if not $derivation; if ($derivation eq 'restriction' ) { # TODO check and probably correct - this includes # all base type's elements in a restriction derivation. # Probably wrong. # # resolve base / get atomic type and run on elements if (my $type_name = $type->get_base()) { my $subtype = $self->get_definitions() ->first_types()->find_type( $type->expand($type_name) ); # visit child elements for (@{ $subtype->get_element() || [] }) { $_->_accept( $self ); } } } elsif ($derivation eq 'extension' ) { # resolve base / get atomic type and run on elements while (my $type_name = $type->get_base()) { $type = $self->get_definitions() ->first_types()->find_type( $type->expand($type_name) ); # visit child elements for (@{ $type->get_element() || [] }) { $_->_accept( $self ); } } } } 1; __END__ =pod =head1 NAME SOAP::WSDL::Generator::Visitor::Typemap - Visitor class for generating typemaps =head1 DESCRIPTION Visitor used by SOAP::WSDL's XSD generator for creating typemaps =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2008, 2009 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: WSDLParser.pm 770 2009-01-24 22:55:54Z kutterma $ $LastChangedDate: 2009-01-24 23:55:54 +0100 (Sa, 24 Jan 2009) $ $LastChangedRevision: 770 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/PrefixResolver.pm010064400017500001750000000074611361135215300215000ustar00scottscottpackage SOAP::WSDL::Generator::PrefixResolver; use strict; use warnings; use Class::Std::Fast::Storable; our $VERSION = 3.004; my %namespace_prefix_map_of :ATTR(:name :default<{}>); my %namespace_map_of :ATTR(:name :default<{}>); my %prefix_of :ATTR(:name :default<{}>); sub resolve_prefix { my ($self, $type, $namespace, $element) = @_; my $prefix; if (not defined($namespace)) { $prefix = $prefix_of{ $$self }->{ $type } } else { $prefix = $namespace_prefix_map_of{ $$self }->{ $namespace } || ( ($namespace_map_of{ $$self }->{ $namespace }) ? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace }) : $prefix_of{ $$self }->{ $type } ); } return "${prefix}::"; } 1; __END__ =pod =head1 NAME SOAP::WSDL::Generator::PrefixResolver - prefixes for different classes =head1 SYNOPSIS If you want to create your custom prefix resolver: package MyPrefixResolver; use strict; use warnings; use base qw(SOAP::WSDL::Generator::PrefixResolver); sub resolve_prefix { my ($self, $type, $namespace, $node) = @_; # return something special return $self->SUPER::resolve_prefix($type, $namespace, $node); } When generating code: use MyPrefixResolver; use SOAP::WSDL::Generator::XSD; my $generator = SOAP::WSDL::Generator::Template::XSD->new({ prefix_resolver_class => 'MyPrefixResolver', }); =head1 DESCRIPTION Prefix resolver class for SOAP::WSDL's code generator. You may subclass it to apply some custom prefix resolving logic. Subclasses must implement the following methods: =over =item * resolve_prefix sub resolve_prefix { my ($self, $namespace, $node) = @_; # ... } resolve_prefix is expected to return a (perl class) prefix. It is called with the following parameters: NAME DESCRIPTION ----------------------------------------------------------------------------- type One of (server|interface|typemap|type|element|attribute) namespace The targetNamespace of the node to generate a prefix for. node The node to generate a prefix for You usually just need type and namespace for prefix resolving. node is provided for rather funky setups, where you have to choose different prefixes based on type names or whatever. Node may be of any of the following classes: SOAP::WSDL::Service SOAP::WSDL::XSD::Attribute SOAP::WSDL::XSD::Element SOAP::WSDL::XSD::Type Note that both namespace and node may be undef - you should test for definedness before doing anything fancy with them. If you want your prefixes to represent perl class hierarchies, they should end with '::'. Example: Imagine you're generating interfaces for the Acme Pet Shop. Acme Corp. has set up their datatypes to be global across all interfaces (and products), while elements are local to the product (the Pet Shop in the example). All elements are in the urn:Acme namespace. In addition, there are types in the namespace urn:Acme:Goods, which should go into the same namespace as types, but be prefixed with 'Goods_' You may want prefixes (roughly) like this: Interfaces: Acme::Client::PetShop:: Server: Acme::Server::PetShop:: Types: Acme::Types:: Types (Goods): Acme::Types::Goods_ Elements: Acme::Elements::PetShop:: Typemaps: Acme::Typemaps::PetShop:: =back =head1 BUGS AND LIMITATIONS You cannot suffix your types by some rule yet... =head1 LICENSE AND COPYRIGHT Copyright 2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 583 $ $LastChangedBy: kutterma $ $Id: $ $HeadURL: $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Template.pm010064400017500001750000000067651361135215300203020ustar00scottscottpackage SOAP::WSDL::Generator::Template; use strict; use warnings; use Template 2.18; use Class::Std::Fast::Storable; use Carp; use SOAP::WSDL::Generator::PrefixResolver; our $VERSION = 3.004; my %tt_of :ATTR(:get); my %definitions_of :ATTR(:name :default<()>); my %server_prefix_of :ATTR(:name :default); my %interface_prefix_of :ATTR(:name :default); my %typemap_prefix_of :ATTR(:name :default); my %type_prefix_of :ATTR(:name :default); my %element_prefix_of :ATTR(:name :default); my %attribute_prefix_of :ATTR(:name :default); my %INCLUDE_PATH_of :ATTR(:name :default<()>); my %EVAL_PERL_of :ATTR(:name :default<0>); my %RECURSION_of :ATTR(:name :default<0>); my %OUTPUT_PATH_of :ATTR(:name :default<.>); my %prefix_resolver_class_of :ATTR(:name :default); sub START { my ($self, $ident, $arg_ref) = @_; } sub _process :PROTECTED { my ($self, $template, $arg_ref, $output) = @_; my $ident = ident $self; # always create a new Template object to # force re-loading of plugins. my $tt = Template->new( DEBUG => 1, EVAL_PERL => $EVAL_PERL_of{ $ident }, RECURSION => $RECURSION_of{ $ident }, INCLUDE_PATH => $INCLUDE_PATH_of{ $ident }, OUTPUT_PATH => $OUTPUT_PATH_of{ $ident }, PLUGIN_BASE => 'SOAP::WSDL::Generator::Template::Plugin', ) or die Template->error(); $tt->process( $template, { context => { prefix_resolver => $prefix_resolver_class_of{ $$self }->new({ namespace_prefix_map => { 'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin', }, namespace_map => { }, prefix => { interface => $self->get_interface_prefix, element => $self->get_element_prefix, attribute => $self->get_attribute_prefix, server => $self->get_server_prefix, type => $self->get_type_prefix, typemap => $self->get_typemap_prefix, } }), }, definitions => $self->get_definitions, NO_POD => delete $arg_ref->{ NO_POD } ? 1 : 0 , %{ $arg_ref } }, $output) or croak $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error(); } 1; =pod =head1 NAME SOAP::WSDL::Generator::Template - Template-based code generator =head1 DESCRIPTION SOAP::WSDL's template based code generator Base class for writing template based generators =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2008, 2009 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: WSDLParser.pm 770 2009-01-24 22:55:54Z kutterma $ $LastChangedDate: 2009-01-24 23:55:54 +0100 (Sa, 24 Jan 2009) $ $LastChangedRevision: 770 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Generator/Visitor.pm010064400017500001750000000207721361135215300201600ustar00scottscottpackage SOAP::WSDL::Generator::Visitor; use strict; use warnings; use Class::Std::Fast::Storable; our $VERSION = 3.004; my %definitions_of :ATTR(:name :default<()>); my %type_prefix_of :ATTR(:name :default<()>); my %element_prefix_of :ATTR(:name :default<()>); sub START { my ($self, $ident, $arg_ref) = @_; $type_prefix_of{ $ident } = 'MyType' if not exists $arg_ref->{ 'type_prefix' }; $element_prefix_of{ $ident } = 'MyElement' if not exists $arg_ref->{ 'element_prefix' }; } # WSDL stuff sub visit_Definitions {} sub visit_Binding {} sub visit_Message {} sub visit_Operation {} sub visit_OpMessage {} sub visit_Part {} sub visit_Port {} sub visit_PortType {} sub visit_Service {} sub visit_SoapOperation {} sub visit_Types {} # XML Schema stuff sub visit_XSD_Schema {} sub visit_XSD_ComplexType {} sub visit_XSD_Element {} sub visit_XSD_SimpleType {} 1; __END__ =head1 NAME SOAP::WSDL::Generator::Visitor - SOAP::WSDL's Visitor-based Code Generator =head1 DESCRIPTION SOAP::WSDL features a code generating facility. This code generation facility (in fact there are several of them) is implemented as Visitor to SOAP::WSDL::Base-derived objects. =head2 The Visitor Pattern The Visitor design pattern is one of the object oriented design pattern described by [GHJV1995]. A Visitor is an object implementing some behaviour for a fixed set of classes, whose implementation would otherwise need to be scattered across those classes' implementations. Visitors are usually combined with Iterators for traversing either a list or tree of objects. A Visitor's methods are called using the so-called double dispatch technique. To allow double dispatching, the Visitor implements one method for every class to be handled, whereas every class implements just one method (commonly named "access"), which does nothing more than calling a method on the reference given, with the self object as parameter. If all this sounds strange, maybe an example helps. Imagine you had a list of person objects and wanted to print out a list of their names (or address stamps or everything else you like). This can easily be implemented with a Visitor: package PersonVisitor; use Class::Std; # handles all basic stuff like constructors etc. sub visit_Person { my ( $self, $object ) = @_; print "Person name is ", $object->get_name(), "\n"; } package Person; use Class::Std; my %name : ATTR(:name :default); sub accept { $_[1]->visit_Person( $_[0] ) } package main; my @person_from = (); for (qw(Gamma Helm Johnson Vlissides)) { push @person_from, Person->new( { name => $_ } ); } my $visitor = PersonVisitor->new(); for (@person_from) { $_->accept($visitor); } # will print Person name is Gamma Person name is Helm Person name is Johnson Person name is Vlissides While using this pattern for just printing a list may look a bit over-sized, it may become handy if you need multiple output formats and different classes to operate on. The main benefits using visitors are: =over =item * Grouping related behaviour in one class Related behaviour for several classes can be grouped together in the Visitor class. The behaviour can easily be changed by changing the code in one class, instead of having to change all the visited classes. =item * Cleaning up the data classes' implementations If classes holding data also implement several different output formats or other (otherwise unrelated) behaviour, they tend to get bloated. =item * Adding behaviour is easy Swapping out the visitor class allows easy alterations of behaviour. So on a list of Persons, one Visitor may print address stamps, while another one prints out a phone number list. =back Of course, there are also drawbacks in the visitor pattern: =over =item * Changes in the visited classes are expensive If one of the visited classes changes (or is added), all visitors must be updated to reflect this change. This may be rather expensive if classes change often. =item * The visited classes must expose all data required Visitors may need to use the internals of a class. This may result in fidelling with a object's internals, or a bloated interface in the visited class. =back Visitors are usually accompanied by a Iterator. The Iterator may be implemented in the visited classes, in the Visitor, or somewhere else (in the example it was somewhere else). The Iterator decides which object to visit next. =head2 Why SOAP::WSDL uses the Visitor pattern for Code Generation Code generation in SOAP::WSDL means generating various artefacts: =over =item * Typemaps For every WSDL definition, a Typemap is created. The Typemap is used later as an aid in parsing the SOAP XML messages. =item * Type Classes For every type defined in the WSDL's schema, a Type Class is generated. These classes are instantiated later as a result of parsing SOAP XML messages. =item * Interface Classes For every service, a interface class is generated. This class is later used by programmers accessing the service =item * Documentation Both Type Classes and Interface Classes include documentation. Additional documentation may be generated as a hint for programmers, or later for mimicking .NET's .asmx example pages. =back All these behaviours could well be (and have historically been) implemented in the classes holding the WSDL data. This made these classes rather bloated, and made it hard to change behaviour (like supporting SOAP Headers, supporting atomic types, and other features which were missing from early versions of SOAP::WSDL). Implementing these behaviours in Visitor classes eases adding new behaviours, and reducing the incompletenesses still inherent in SOAP::WSDL's WSDL and XML schema implementation. =head2 Implementation =head3 accept SOAP::WSDL::Base defines an accept method which expects a Visitor as only parameter. The method visit_Foo_Bar is called on the visitor, with the self object as parameter. The actual method name is constructed this way: =over =item * SOAP::WSDL is stripped from the class name =item * All remaining :: s are replaced by _ =back Example: When visiting a SOAP::WSDL::XSD::ComplexType object, the method visit_XSD_ComplexType is called on the visitor. =head2 Writing your own visitor SOAP::WSDL eases writing your own visitor. This might be required if you need some special output format from a WSDL file or want to feed your own serializer/deserializer pair with custom configuration data. Or maybe you want to generate C# code from it... To write your own code generating visitor, you should subclass SOAP::WSDL::Generator::Visitor. It implements (empty) default methods for all SOAP::WSDL data classes: =over =item * visit_Definitions =item * visit_Binding =item * visit_Message =item * visit_Operation =item * visit_OpMessage =item * visit_Part =item * visit_Port =item * visit_PortType =item * visit_Service =item * visit_SoapOperation =item * visit_Types =item * visit_XSD_Schema =item * visit_XSD_ComplexType =item * visit_XSD_Element =item * visit_XSD_SimpleType =back In your Visitor, you must implement visit_Foo methods for all classes you wish to visit. The SOAP::WSDL::Generator::Visitor implementations include part of their own Iterator (which means they know how to find the next objects to visit). You may or may not choose to implement a separate Iterator. Letting a visitor implementing its own Iterator visit a WSDL definition is as easy as writing something like this: my $visitor = MyVisitor->new(); my $parser = SOAP::WSDL::Expat::WSDLParser->new(); my $definitions = $parser->parse_file('my.wsdl'): $definitions->_accept( $visitor ); If you need an iterator following the somewhat crude path of dependencies in a WSDL1.1 definition, you might want to look at L. =head1 REFERENCES =over =item * [GHJV1995] Erich Gamma, Richard Helm, Ralph E. Johnson, John Vlissides, (1995): Design Patterns. Elements of Reusable Object-Oriented Software. Addison-Wesley Longman, Amsterdam. =back =head1 LICENSE AND COPYRIGHT Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 391 $ $LastChangedBy: kutterma $ $Id: Client.pm 391 2007-11-17 21:56:13Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD004075500017500001750000000000001361135364200146135ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib004075500017500001750000000000001361135364200162235ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin004075500017500001750000000000001361135364200176315ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm010064400017500001750000000003271237511274000230770ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm010064400017500001750000000003421237511274000213410ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::NCName; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::Name); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm010064400017500001750000000006241237511274000235760ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::normalizedString; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::string); # replace all \t, \r, \n by \s sub set_value { my $value = $_[1]; $value =~ s{ [\r\n\t]+ }{ }xmsg if defined($value); $_[0]->SUPER::set_value($value); } Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm010064400017500001750000000003401237511274000233560ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm010064400017500001750000000017051237511274000212170ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::list; use strict; use warnings; sub serialize { my ($self, $opt) = @_; $opt = {} if not $opt; my $value = $self->get_value(); return $self->start_tag({ %$opt, nil => 1 }) if not defined $value; $value = [ $value ] if not ref $value; return join q{}, $self->start_tag($opt, $value) , join( q{ }, @{ $value } ) , $self->end_tag($opt, $value); } 1; __END__ =pod =head1 NAME SOAP::WSDL::XSD::Typelib::Builtin::list - list derivation base class =head1 DESCRIPTION To derive from some class by list, just inherit from list. Make sure SOAP::WSDL::XSD::Typelib::Builtin::list is before the type to derive from in the @ISA list. =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =cutSOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm010064400017500001750000000003061237511274000210320ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::int; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::long); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm010064400017500001750000000026771361135215300212110ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::time; use strict; use warnings; use Date::Parse; use Date::Format; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); our $VERSION = 3.004; 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.. # we need to set the current date for correct TZ conversion - # could be daylight savings time my @now = localtime; my @time_from = map { my $alternative = shift @now; ! defined $_ ? $alternative : $_ } strptime($_[1]); undef $time_from[-1]; my $time_str = strftime( '%H:%M:%S%z', @time_from ); substr $time_str, -2, 0, ':'; $_[0]->SUPER::set_value($time_str); } } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm010064400017500001750000000003301237511274000240300ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm010064400017500001750000000003401237511274000234160ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm010064400017500001750000000015431237511274000215520ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::string; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); my %char2entity = ( q{&} => q{&}, q{<} => q{<}, q{>} => q{>}, q{"} => q{"}, q{'} => q{'}, ); sub serialize { $_[1] ||= {}; my $value = $_[0]->get_value(); return $_[0]->start_tag({ %{ $_[1] }, nil => 1}) if not defined $value; # HTML::Entities does the same - and more, thus it's around 1/3 slower... $value =~ s{([&<>"'])}{$char2entity{$1}}xgmso; return join q{}, $_[0]->start_tag($_[1], $value) #, encode_entities( $value, q{&<>"'} ) , $value , $_[0]->end_tag($_[1]); } sub as_bool :BOOLIFY { return $_[0]->get_value(); } Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm010064400017500001750000000003441237511274000212560ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::ENTITY; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm010064400017500001750000000003321237511274000224700ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::base64Binary; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm010064400017500001750000000005221237511274000213450ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::float; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub as_num :NUMERIFY { return $_[0]->get_value(); } Class::Std::initialize(); # make :NUMERIFY overloading serializable 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm010064400017500001750000000003211237511274000213040ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::gYear; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm010064400017500001750000000003411237511274000212020ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::byte; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::short); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm010064400017500001750000000003261237511274000223170ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm010064400017500001750000000003261237511274000225310ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm010064400017500001750000000031771361134305500220040ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::dateTime; use strict; use warnings; use Date::Parse; use Date::Format; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub set_value { # use set_value from base class if we have a XML-DateTime format #2037-12-31T00:00:00.0000000+01:00 return $_[0]->SUPER::set_value( $_[1] ) if not defined $_[1]; return $_[0]->SUPER::set_value( $_[1] ) if ( $_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2} T \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )? [\+\-] \d{2} \: \d{2} $ }xms ); # strptime sets empty values to undef - and strftime doesn't like that... my @time_from = strptime( $_[1] ); die "Illegal date" if not defined $time_from[5]; # strftime doesn't like undefs @time_from = map { !defined $_ ? 0 : $_ } @time_from; my $time_str; if ( $time_from[6] ) { # if we parsed a timezone # don't think this works, ever. if this path is taken, we wind up with something like 2007-08-31T00:32:00.0000000+00:00. $time_str = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d.0000000%+03d:%02d', $time_from[5] + 1900, $time_from[4] + 1, $time_from[3], $time_from[2], $time_from[1], $time_from[0], int( $time_from[6] / 3600 ), int( $time_from[6] % 3600 ) / 60 ); } else { $time_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from ); substr $time_str, -2, 0, ':'; } $_[0]->SUPER::set_value($time_str); } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm010064400017500001750000000040721361135215300216730ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::anyType; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; our $VERSION = 3.004; sub get_xmlns { 'http://www.w3.org/2001/XMLSchema' }; # start_tag creates a XML start tag either for a XML element or a attribute. # The method is highly optimized for performance: # - operates on @_ # - uses no private variables # - uses no blocks sub start_tag { # return empty string if no second argument ($opt) or no name return q{} if (! $#_); return q{} if (! exists $_[1]->{ name }); # return attribute start if it's an attribute return qq{ $_[1]->{name}="} if $_[1]->{ attr }; # return with xsi:nil="true" if it is nil return join q{} , "<$_[1]->{ name }" , (defined $_[1]->{ xmlns }) ? qq{ xmlns="$_[1]->{ xmlns }"} : (), $_[0]->serialize_attr($_[1]) , q{ xsi:nil="true"/>} if ($_[1]->{ nil }); # return "empty" start tag if it's empty return join q{}, "<$_[1]->{ name }", (defined $_[1]->{ xmlns }) ? qq{ xmlns="$_[1]->{ xmlns }"} : (), $_[0]->serialize_attr($_[1]) , '/>' if ($_[1]->{ empty }); # return XML element start tag return join q{}, "<$_[1]->{ name }", (defined $_[1]->{ xmlns }) ? qq{ xmlns="$_[1]->{ xmlns }"} : (), , $_[0]->serialize_attr($_[1]) , '>'; } # start_tag creates a XML end tag either for a XML element or a attribute. # The method is highly optimized for performance: # - operates on @_ # - uses no private variables # - uses no blocks sub end_tag { # return empty string if no second argument ($opt) or no name return q{} if (! $#_); return q{} if (! exists $_[1]->{ name }); return q{"} if $_[1]->{ attr }; return "{name}>"; }; sub serialize_attr {}; # sub serialize { q{} }; sub serialize_qualified :STRINGIFY { return $_[0]->serialize( { qualified => 1 } ); } sub as_list :ARRAYIFY { return [ $_[0] ]; } Class::Std::initialize(); # make :STRINGIFY overloading work 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm010064400017500001750000000003551237511274000213640ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::token; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::normalizedString); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm010064400017500001750000000003231237511274000214060ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::anyURI; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm010064400017500001750000000034011237511274000230420ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use SOAP::WSDL::XSD::Typelib::Builtin::anyType; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); my %value_of :ATTR(:get :init_arg :default<()>); # don't you never dare to play with this ! our $___value = \%value_of; ## use $_[n] for speed - we get called zillions of times... # and we don't need to return the last value... sub set_value { $value_of{ ${ $_[0] } } = $_[1] } # Default attribute handling # TODO add something for handling default attributes sub attr { } # use $_[n] for speed. # This is less readable, but notably faster. # # use postfix-if for speed. This is slightly faster, as it saves # perl from creating a pad (variable context). # # The methods below may get called zillions of times, so # every little statement matters... sub serialize { $_[1] ||= {}; if (not defined $value_of{ ${$_[0]} }) { return $_[0]->start_tag({ %{ $_[1] }, nil => 1 }, undef); } return join q{} , $_[0]->start_tag($_[1], $value_of{ ${$_[0]} }) , $value_of{ ${$_[0]} } , $_[0]->end_tag($_[1]); } sub as_string :STRINGIFY { return defined($value_of { ${ $_[0] } }) ? $value_of { ${ $_[0] } } : q{}; } sub as_bool :BOOLIFY { return $value_of { ${ $_[0] } }; } my $OBJECT_CACHE_REF = Class::Std::Fast::OBJECT_CACHE_REF(); sub new { my $self = pop @{ $OBJECT_CACHE_REF->{ $_[0] } }; $self = bless \(my $o = Class::Std::Fast::ID()), $_[0] if not defined $self; $value_of{ $$self } = $_[1]->{ value } if (($#_) && exists $_[1]->{ value }); return $self; } Class::Std::initialize(); # make :BOOLIFY overloading serializable 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm010064400017500001750000000043271237511274000211640ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::date; use strict; use warnings; use Date::Parse; use Date::Format; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub set_value { # use set_value from base class if we have a XML-DateTime format #2037-12-31+01:00 if ( $_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2} (:? [\+\-] \d{2} \: \d{2} )$ }xms ) { $_[0]->SUPER::set_value($_[1]) } # converting a date is hard work: It needs a timezone, because # 2007-12-30+12:00 and 2007-12-31-12:00 mean the same day - just in # different locations. # strftime actually prints out the correct date, but always prints the # local timezone with %z. # So, if our timezone is not 0, we strftime it without timezone and # append it by hand by the following formula: # The timezone hours are the int (timesone seconds / 3600) # The timezone minutes (if someone ever specifies something like that) # are int( (seconds % 3600) / 60 ) # say, int( (seconds modulo 3600) / 60 ) # # If we have no timezone (meaning the timezone is else { # strptime sets empty values to undef - and strftime doesn't like that... my @time_from = strptime($_[1]); my $time_zone_seconds = $time_from[6]; @time_from = map { (! defined $_) ? 0 : $_ } @time_from; # use Data::Dumper; # warn Dumper \@time_from, sprintf('%+03d%02d', $time_from[6] / 3600, $time_from[6] % 60 ); my $time_str; if (defined $time_zone_seconds) { $time_str = sprintf('%04d-%02d-%02d%+03d:%02d', $time_from[5]+1900, $time_from[4]+1, $time_from[3], int($time_from[6] / 3600), int($time_from[6] % 3600) / 60); } else { $time_str = strftime( '%Y-%m-%d%z', @time_from ); substr $time_str, -2, 0, ':'; } # ? strftime( '%Y-%m-%d', @time_from ) # . sprintf('%+03d%02d', int($time_from[6] / 3600), int ( ($time_from[6] % 3600) / 60 ) ) # : do { # strftime( '%Y-%m-%d%z', @time_from ); # }; # substr $time_str, -2, 0, ':'; $_[0]->SUPER::set_value($time_str); } } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm010064400017500001750000000004301237511274000214740ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::list SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm010064400017500001750000000003441237511274000213550ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm010064400017500001750000000005531237511274000216420ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::decimal; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub as_num :NUMERIFY :BOOLIFY { return $_[0]->get_value(); } Class::Std::Fast::initialize(); # make :NUMERIFY :BOOLIFY overloading serializable 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm010064400017500001750000000003071237511274000205350ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::ID; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm010064400017500001750000000002521237511274000220230ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::language; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm010064400017500001750000000003241237511274000214730ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::NOTATION; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm010064400017500001750000000004411237511274000214740ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::gMonth; use strict; use warnings; # Speed up. Class::Std::new is slow - and we don't need it's functionality... use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm010064400017500001750000000003241237511274000220650ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::duration; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm010064400017500001750000000005221237511274000215120ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::double; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub as_num :NUMERIFY { return $_[0]->get_value(); } Class::Std::initialize(); # make :NUMERIFY overloading serializable 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm010064400017500001750000000003061237511274000210710ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::IDREF; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::ID); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm010064400017500001750000000003151237511274000216750ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::integer; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::decimal); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm010064400017500001750000000003251237511274000221330ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm010064400017500001750000000003201237511274000211200ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::gDay; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm010064400017500001750000000003301237511274000226750ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm010064400017500001750000000003251237511274000221720ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::hexBinary; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm010064400017500001750000000003221237511274000212370ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::QName; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm010064400017500001750000000020661361135215300216620ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::boolean; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; our $VERSION = 3.004; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType); sub serialize { $_[1] ||= {}; my $value =$_[0]->get_value(); return $_[0]->start_tag({ %{$_[1]}, nil => 1}) if not defined $value; return join q{} , $_[0]->start_tag($_[1]) , $value && $value ne 'false' ? 'true' : 'false' , $_[0]->end_tag($_[1]); } sub as_string :STRINGIFY { my $value = $_[0]->get_value(); return q{} if not defined $value; return ($value && $value ne 'false') ? 1 : 0; } sub as_num :NUMERIFY :BOOLIFY { my $value = $_[0]->get_value(); return ($value && $value ne 'false') ? 1 : 0; } sub set_value { $_[0]->SUPER::set_value( defined $_[1] ? ($_[1] ne 'false' && ($_[1]) ) ? 1 : 0 : 0); } sub delete_value { $_[0]->SUPER::set_value(undef) } Class::Std::Fast::initialize(); # make :BOOLIFY overloading serializable 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm010064400017500001750000000003351237511274000226760ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm010064400017500001750000000003121237511274000211740ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::long; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm010064400017500001750000000003071237511274000214000ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::short; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::int); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm010064400017500001750000000003301237511274000240700ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm010064400017500001750000000003411237511274000211170ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::Name; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token); Class::Std::initialize(); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm010064400017500001750000000003731237511274000212200ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin::IDREFS; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw( SOAP::WSDL::XSD::Typelib::Builtin::list SOAP::WSDL::XSD::Typelib::Builtin::IDREF); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm010064400017500001750000000005521361135215300212520ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::AttributeSet; use strict; use warnings; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); our $VERSION = 3.004; sub serialize { # we work on @_ for performance. # $_[1] ||= {}; # $option_ref # TODO: What about namespaces? return ${ $_[0]->_serialize({ attr => 1 }) }; } 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm010064400017500001750000000571121361135215300211100ustar00scottscott#!/usr/bin/perl package SOAP::WSDL::XSD::Typelib::ComplexType; use strict; use warnings; use Carp; use SOAP::WSDL::XSD::Typelib::Builtin; use Scalar::Util qw(blessed); use Data::Dumper; require Class::Std::Fast::Storable; use Class::Load (); use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); our $VERSION = 3.004; # remove in 2.1 our $AS_HASH_REF_WITHOUT_ATTRIBUTES = 0; my %ELEMENT_FORM_QUALIFIED_OF; # denotes whether elements are qualified my %ELEMENTS_FROM; # order of elements in a class my %ATTRIBUTES_OF; # references to value hashes my %CLASSES_OF; # class names of elements in a class my %NAMES_OF; # XML names of elements in a class # XML Attribute handling my %xml_attr_of :ATTR(); # Namespace handling my %xmlns_of :ATTR(); # don't you ever dare to use this ! our $___attributes_of_ref = \%ATTRIBUTES_OF; our $___xml_attribute_of_ref = \%xml_attr_of; # STORABLE_ methods for supporting Class::Std::Fast::Storable. # We could also handle them via AUTOMETHOD, # but AUTOMETHOD should always croak... # Actually, AUTOMETHOD is faster (~1%) if Class::Std::Fast is loaded # properly, and slower (~10%) if not. # Hmmm. Trade 1% for 10? my %STORABLE_METHODS = ( STORABLE_freeze_pre => undef, STORABLE_freeze_post => undef, STORABLE_thaw_pre => undef, STORABLE_thaw_post => undef, ); # for error reporting. Eases working with data objects... sub AUTOMETHOD { # return before unpacking @_ for speed reasons return if exists $STORABLE_METHODS{$_}; my ($self, $ident, @args_from) = @_; my $class = ref $self || $self or die "Cannot call AUTOMETHOD as function"; # Test whether we're called from ->can() my @caller = caller(1); # return if not called by AUTOLOAD - caller must be something like can() # Unfortunately we cannot test for "UNIVERSAL::can", as it gets overwritten # by both Class::Std and Class::Std::Fast, and we don't know the loading # order (Class::Std::Fast should be loaded before for maximum speedup) return if $caller[3] ne 'Class::Std::AUTOLOAD'; confess "Can't locate object method \"$_\" via package \"$class\". \n" . "Valid methods are: " . join(', ', map { ("get_$_" , "set_$_") } keys %{ $ATTRIBUTES_OF{ $class } }) . "\n" } sub attr { # We're working on @_ for speed. # Normally, the first line would look like this: # my $self = shift; my $class = $_[0]->__get_attr_class() or return; # pass arguments to attributes constructor (if any); # lets attr($foo) work as setter if ($_[1]) { return $xml_attr_of{ ${$_[0]} } = $class->new($_[1]); } return $xml_attr_of{ ${$_[0]} } if exists $xml_attr_of{ ${$_[0]} }; return $xml_attr_of{ ${$_[0]} } = $class->new(); } sub serialize_attr { return q{} if not $xml_attr_of{ ${ $_[0] } }; return $xml_attr_of{ ${ $_[0] } }->serialize(); } # TODO: are complextypes are always true ? sub as_bool :BOOLIFY { 1 } sub as_hash_ref { # we're working on $_[0] for speed (as always...) # # Normally the first line would read: # my ($self, $ignore_attributes) = @_; # my $attributes_ref = $ATTRIBUTES_OF{ ref $_[0] }; 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] } }; $hash_of_ref->{ $attribute } = blessed $value ? $value->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ? $value->get_value() : $value->as_hash_ref($_[1]) : ref $value eq 'ARRAY' ? [ map { $_->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ? $_->get_value() : $_->as_hash_ref($_[1]) } @{ $value } ] : die "Neither blessed obj nor list ref"; }; } # $AS_HASH_REF_WITHOUT_ATTRIBUTES is deprecated by NOW and will be removed # in 2.1 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; } # we store per-class elements. # call as __PACKAGE__->_factory sub _factory { my $class = shift; $ELEMENTS_FROM{ $class } = shift; $ATTRIBUTES_OF{ $class } = shift; $CLASSES_OF{ $class } = shift; $NAMES_OF{ $class } = shift; no strict qw(refs); no warnings qw(redefine); while (my ($name, $attribute_ref) = each %{ $ATTRIBUTES_OF{ $class } } ) { my $type = $CLASSES_OF{ $class }->{ $name } or croak "No class given for $name"; # require all types here Class::Load::is_class_loaded($type) or eval { Class::Load::load_class $type } or croak $@; # check now, so we don't need to do it later. # $is_list is used in the methods created. Filling it now means # we don't have to check it every time the method is called, but # can just use $is_list, which will hold the value assigned to # it when the method was created. my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list'); # The set_$name method 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 child 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 or SCALAR 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 ! # keep in sync with Generator::Template::Plugin::XSD - maybe use # function to allow substituting via symbol table... 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 # remembered from outside closure ? $type->new({ value => $_[1] }) # it's a list element - can take list ref as value : [ map { # it's not a list element - set value to list of objects ref $_ ? ref $_ eq 'HASH' ? $type->new($_) : ref $_ eq $type ? $_ : croak "cannot use " . ref($_) . " reference as value for $name - $type required" : $type->new({ value => $_ }) } @{ $_[1] } ] : $is_ref eq 'HASH' ? $type->new( $_[1] ) # neither ARRAY nor HASH - probably an object... - # do we need to test for it being blessed? : blessed $_[1] && $_[1]->isa($type) # of required type ? ? $_[1] # use it : die croak "cannot use $is_ref reference as value for $name - $type required" # not $is_ref : 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]; # first call # test for existance, not for definedness if (not exists $attribute_ref->{ ${ $_[0]} }) { $attribute_ref->{ ${ $_[0]} } = $_[1]; return; } if (not ref $attribute_ref->{ ${ $_[0]} } eq 'ARRAY') { # second call: listify previous value if it's no list and add current $attribute_ref->{ ${ $_[0]} } = [ $attribute_ref->{ ${ $_[0]} }, $_[1] ]; return; } # second and following: add to list push @{ $attribute_ref->{ ${ $_[0]} } }, $_[1]; return; }; } # TODO Could be moved as normal method into base class, e.g. here. # Hmm. let's see... *{ "$class\::new" } = sub { # We're working on @_ for speed. # Normally, the first line would look like this: # my ($class, $args_of) = @_; # # The hanging side comment show you what would be there, then. # Read as: # my $self = bless \(my $o = Class::Std::Fast::ID()), $class; my $self = bless \(my $o = Class::Std::Fast::ID()), $_[0]; # Set attributes if passed via { xmlattr => \%attributes } # # This works just because # a) xmlattr cannot be used as valid XML identifier (it starts # with "xml" which is banned by the XML schema standard) # b) $o->attr($attribute_ref) passes $attribute_ref to the # attribute object's constructor # c) we are in the object's constructor here (which means that) # no attributes object can have been legally constructed # before. if (exists $_[1]->{xmlattr}) { # $args_of->{xmlattr} $self->attr(delete $_[1]->{xmlattr}); } # iterate over keys of arguments # and call set appropriate field in clase map { ($ATTRIBUTES_OF{ $class }->{ $_ }) ? do { my $method = "set_$_"; # keep in sync with Generator::Template::Plugin::XSD - maybe use # function to allow substituting via symbol table... $method =~s{[\.\-]}{_}xmsg; $self->$method( $_[1]->{ $_ } ); # ( $args_of->{ $_ } ); } : $_ =~ m{ \A # beginning of string xmlns # xmlns }xms # get_elements is inlined for performance. ? () : do { croak "unknown field $_ in $class. Valid fields are:\n" . join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n" . "Structure given:\n" . Dumper @_ }; } keys %{ $_[1] }; # %$args_of; return $self; }; # this _serialize method works fine for and # complextypes, as well as for or # , and attribute sets. # # But what about choice, extension ? # # Triggers XML attribute serialization if the options hash ref contains # a attr element with a true value. *{ "$class\::_serialize" } = sub { my $ident = ${ $_[0] }; my $option_ref = $_[1]; # return concatenated return value of serialize call of all # elements retrieved from get_elements expanding list refs. 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'; # use || $_; for backward compatibility my $name = $NAMES_OF{$class}->{$_} || $_; my $target_namespace = $_[0]->get_xmlns(); map { # serialize element elements with their own serializer # but name them like they're named here. # TODO: check. element ref="" has a name??? if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) { # serialize elements of different namespaces # with namespace declaration ($target_namespace ne $_->get_xmlns()) ? $_->serialize({ name => $name, qualified => 1 }) : $_->serialize({ name => $name }); } # serialize complextype elments (of other types) with their # serializer, but add element tags around. else { # default for undef is true if (! defined $ELEMENT_FORM_QUALIFIED_OF{ $class } or $ELEMENT_FORM_QUALIFIED_OF{ $class } ) { # handle types from different namespaces # # serialize with last namespace put on stack # if the last namespace is a change from the # before-last # if ( exists $option_ref->{ xmlns_stack } && (scalar @{ $option_ref->{ xmlns_stack } } >= 2) && ($option_ref->{ xmlns_stack }->[-1] ne $option_ref->{ xmlns_stack }->[-2])) { # warn "New namespace: ", $option_ref->{ xmlns_stack }->[-1]; join q{}, $_->start_tag({ name => $name , xmlns => $option_ref->{ xmlns_stack }->[-1], %{ $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 { # in elementFormDefault="unqualified" mode, # the serialize method has to set # xmnlns="" on all elements inside a ComplexType # # Other serializers usually use prefixes # for "unqualified" and just omit all prefixes # for inner elements # check whether we "had" a xmlns around my $set_xmlns = delete $option_ref->{xmlns}; # serialize start tag with xmlns="" if out parent # did not do that join q{}, $_->start_tag({ name => $name, %{ $option_ref }, (! defined $set_xmlns) ? (xmlns => "") : () }) # add xmlns = "" to child serialize options # to avoid putting xmlns="" everywhere , $_->serialize({ %{$option_ref}, xmlns => "" }) , $_->end_tag({ name => $name , %{ $option_ref } }); } } } @{ $element } } else { q{}; } } (@{ $ELEMENTS_FROM{ $class } }); }; # put hidden complex serializer into class # ... but not for AttributeSet classes if ( ! $class->isa('SOAP::WSDL::XSD::Typelib::AttributeSet')) { *{ "$class\::serialize" } = \&__serialize_complex; }; } sub _set_element_form_qualified { $ELEMENT_FORM_QUALIFIED_OF{ $_[0] } = $_[1]; } # Just as fallback: return no attribute set class as default. # Subclasses may override sub __get_attr_class {}; # hidden complex serializer sub __serialize_complex { # we work on @_ for performance. $_[1] ||= {}; # $option_ref push @{ $_[1]->{ xmlns_stack } }, $_[0]->get_xmlns(); # get content first (pass by reference to avoid copying) my $content_ref = $_[0]->_serialize($_[1]); # option_ref pop @{ $_[1]->{ xmlns_stack } }; # do we have a empty element ? return $_[0]->start_tag({ %{ $_[1] }, empty => 1 }) if not length ${ $content_ref }; return join q{}, $_[0]->start_tag($_[1]), ${ $content_ref }, $_[0]->end_tag(); } sub get_xmlns { return q{} } 1; __END__ =pod =head1 NAME SOAP::WSDL::XSD::Typelib::ComplexType - Base class for complexType node classes =head1 Subclassing To subclass, write a package like this: package MyComplexType; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); # we only need the :get attribute qualifier. # set and init_arg are automatically created by # SOAP::WSDL::XSD::Typelib::ComplexType my %first_attr_of :ATTR(:get :default<()>); my %second_attr_of :ATTR(:get :default<()>); my %third_attr_of :ATTR(:get :default<()>); # the order of elements in a complexType my @elements_from = qw(first_attr second_attr third_attr); # references to the private hashes my %attribute_of = ( first_attr => \%first_attr_of, second_attr => \%second_attr_of, third_attr => \%third_attr_of, ); # classes_of: Classes the child elements should be of my %classes_of = ( first_attr => 'My::FirstElement', second_attr => 'My::SecondElement', third_attr => 'My::ThirdElement', ); # call _factory __PACKAGE__->_factory( \@elements_from, \%attributes_of, \%classes_of, ); 1; 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. The special key B may be used to pass XML attributes. This key is chosen, because "xmlattr" cannot legally be used as XML name (it starts with "xml"). Passing a hash ref structure as value to "xmlattr" has the same effect as passing the same structure to a call to C<$obj->attr()> 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 ], }); my $obj = MyClass->new({ xmlattr => { name => 'foo' }, MyName => { DeepName => $value, }, MySecondName => $value, }); In case your building on Class::Std, please note the following limitations: The new() method from Class::Std will be overridden, so you should not rely on it's behaviour. Your START and BUILD methods are called, but the class' inheritance tree is not traversed. =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. Note that you cannot delete a property by setting it to undef - this sets the property to an empty property object (with value undef). To delete a property, say: $obj->set_FOO(); =head2 attr Returns / sets the attribute object associated with the object. XML Attributes are modeled as attribute objects - their classes are usually private (i.e. part of the associated class' file, not in a separate file named after the attribute class). Note that attribute support is still experimental. =head2 as_bool Returns the boolean value of the complexType (always true). =head2 as_hash_ref Returns a hash ref representation of the complexType object Attributes are included under the special key "xmlattr" (if any). The inclusion of attributes can be suppressed by calling $obj->as_has_ref(1); or even globally by setting $SOAP::WSDL::XSD::Typelib::ComplexType::AS_HASH_REF_WITHOUT_ATTRIBUTES = 1; Note that using the $AS_HASH_REF_WITHOUT_ATTRIBUTES global variable is strongly discouraged. Use of this variable is deprecated and will be removed as of version 2.1 as_hash_ref can be used for deep cloning. The following statement creates a deep clone of a SOAP::WSDL::ComplexType-based object my $clone = ref($obj)->new($obj->as_hash_ref()); =head2 serialize_attr Serialize a complexType's attributes =head2 serialize Serialize a ComplexType object to XML. Exported via symbol table into derived classes. =head1 Bugs and limitations =over =item * Incomplete API Not all variants of XML Schema ComplexType definitions are supported yet. Variants known to work are: sequence all complexContent containing sequence/all definitions =item * Thread safety SOAP::WSDL::XSD::Typelib::Builtin::ComplexType uses Class::Std::Fast::Storable which uses Class::Std. Class::Std is not thread safe, so SOAP::WSDL::XSD::Typelib::Builtin::ComplexType is neither. =item * XML Schema facets No facets are implemented yet. =back =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: ComplexType.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Attribute.pm010064400017500001750000000006661361135215300206040ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Attribute; use strict; use warnings; use base qw(SOAP::WSDL::XSD::Typelib::Element); our $VERSION = 3.004; sub start_tag { # my ($self, $opt, $value) = @_; return q{} if (@_ < 3); my $ns = $_[0]->get_xmlns(); if ($ns eq 'http://www.w3.org/XML/1998/namespace') { return qq{ xml:$_[1]->{ name }="}; } return qq{ $_[1]->{ name }="}; } sub end_tag { return q{"}; } 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Element.pm010064400017500001750000000111551361135215300202250ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Element; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; our $VERSION = 3.004; my %NAME; my %NILLABLE; my %REF; my %MIN_OCCURS; my %MAX_OCCURS; # TODO replace by generated methods? # # Class data - remember, we're the base class for a class factory or for # generated code... # use BLOCK: for scoping BLOCK: { my %method_lookup = ( _name => \%NAME, _nillable => \%NILLABLE, _ref => \%REF, _minOccurs => \%MIN_OCCURS, _maxOccurs => \%MAX_OCCURS, ); # create getters / setters for all elements' class data no strict qw(refs); while (my ($name, $value) = each %method_lookup ) { *{ "__set$name" } = sub { @_ or die "Cannot call __set$name without parameter"; my $class = ref $_[0] || $_[0]; $value->{ $class } = $_[1]; }; *{ "__get$name" } = sub { @_ or die "Cannot call __set$name as function"; my $class = ref $_[0] || $_[0]; return $value->{ $class }; }; } }; # use $_[0] and $_[1] for speed. sub start_tag { # my ($self, $opt, $value) = @_; my $ending = ($_[1]->{ empty }) ? '/>' : '>'; my @attr_from = (); if ($_[1]->{ nil }) { return q{} if not $NILLABLE{ ref $_[0] }; push @attr_from, q{ xsi:nil="true"}; $ending = '/>'; } if (delete $_[1]->{qualified}) { push @attr_from, q{ xmlns="} . $_[0]->get_xmlns() . q{"}; } push @attr_from, $_[0]->serialize_attr(); # do we need to check for name ? Element ref="" should have it's own # start_tag. If we don't need to check, we can speed things up return join q{}, "<$_[1]->{ name }" , @attr_from , $ending if $_[1]->{ name }; return join q{}, "<$NAME{ ref $_[0]}" , @attr_from , $ending; } # use $_[0] and $_[1] for speed. # # read it as: # # my ($self, $opt) = @_; # my $class = ref $self; # return "{name}>" if $opt->{name}; # return ""; # # do we need to check for name ? Element ref="" should have it's own # end_tag. If we don't need to check, we can speed things up by defining # end tag with () prototype - perl will inline it for us if we do... sub end_tag { return "{name}>" if $_[1]->{name}; return ""; } 1; =pod =head1 NAME SOAP::WSDL::XSD::Typelib::Element - element base clase =head1 SYNOPSIS This example creates a class for this XML schema definition: package MyElement; use strict; use Class::Std::Fast::Storable constructor => 'none'; use base ( '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(0); Now we create this XML schema definition type class: package MyElement2; use strict; use Class::Std::Fast::Storable constructor => 'none'; 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 not implemented These attributes are not yet supported, though they may be set as class properties via __PACKAGE__->__set_FOO methods. =item * 'http://www.w3.org/2001/XMLSchema-instance prefix is hardcoded The prefix for 'http://www.w3.org/2001/XMLSchema-instance (used as namespace for the {http://www.w3.org/2001/XMLSchema-instance}nil="true" attribute is hardcoded as 'xsi'. You should definitely provide your XML envelope generator with the same prefix namespace combination (Default for SOAP::WSDL::Envelope). =back =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Element.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/Element.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm010064400017500001750000000075131361135215300207320ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::SimpleType; use strict; use warnings; use SOAP::WSDL::XSD::Typelib::Builtin; our $VERSION = 3.004; package SOAP::WSDL::XSD::Typelib::SimpleType::restriction; use strict; use SOAP::WSDL::XSD::Typelib::Builtin; use base qw(SOAP::WSDL::XSD::Typelib::SimpleType); our $VERSION = 3.004; 1; __END__ =pod =head1 NAME SOAP::WSDL::XSD::Typelib::SimpleType - simpleType base class =head1 DESCRIPTION This module implements a base class for designing simple type classes modelling XML Schema simpleType definitions. =head1 SYNOPSIS # example simpleType derived by restriction # XSD would be: # # # package MySimpleType; use Class::Std::Fast::Storable constructor => 'none'; # restriction base implemented via inheritance use SOAP::WSDL::XSD::Typelib::Builtin; use SOAP::WSDL::XSD::Typelib::SimpleType; use base qw( # derive by restriction 'SOAP::WSDL::XSD::Typelib::SimpleType::restriction', # restriction base 'SOAP::WSDL::XSD::Typelib::Builtin::string' ); # example simpleType derived by list. # XSD would be: # # # package MySimpleListType; use Class::Std::Fast::Storable constructor => 'none'; # restriction base implemented via inheritance use SOAP::WSDL::XSD::Typelib::Builtin; use base ('SOAP::WSDL::XSD::Typelib::SimpleType', 'SOAP::WSDL::XSD::Typelib::Builtin::list', # derive by list 'SOAP::WSDL::XSD::Typelib::Builtin::string' # list itemType ); =head1 How to write your own simple type Writing a simple type class is easy - all you have to do is setting up the base classes correctly. The following rules apply: =over =item * simpleType derived via list simpleType classes derived via list must inherit from these classes in exactly this order: SOAP::WSDL::XSD::Typelib::SimpleType SOAP::WSDL::XSD::Typelib::Builtin::list # derive by list The::List::ItemType::Class # list itemType The::List::ItemType::Class can either be a builtin class (see SOAP::WSDL::XSD::Builtin) or another simpleType class (any other class implementing the right methods is supported too, but not for the faint of heart). =item * simpleType derived via restriction simpleType classes derived via restriction must inherit from these classes in exactly this order: SOAP::WSDL::XSD::Typelib::SimpleType # you may leave this out SOAP::WSDL::XSD::Typelib::SimpleType::restriction # derive by restriction The::Restriction::Base::Class # restriction base The::Restriction::Base::Class can either be a builtin class (see SOAP::WSDL::XSD::Builtin) or another simpleType class. The slight inconsistency between the these variants is caused by the restriction element, which has different meanings for simpleType and complexType definitions. =back =head1 BUGS AND LIMITATIONS =over =item * Thread safety SOAP::WSDL::XSD::Typelib::SimpleType uses Class::Std::Fast::Storable which uses Class::Std. Class::Std is not thread safe, so SOAP::WSDL::XSD::Typelib::SimpleType is neither. =item * union union simple types are not supported yet. =item * XML Schema facets No facets are implemented yet. =back =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: SimpleType.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Typelib/Builtin.pm010064400017500001750000000265631361135215300202530ustar00scottscottpackage SOAP::WSDL::XSD::Typelib::Builtin; use strict; use warnings; use Class::Std::Fast::Storable; our $VERSION = 3.004; use SOAP::WSDL::XSD::Typelib::Builtin::anyType; use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use SOAP::WSDL::XSD::Typelib::Builtin::anyURI; use SOAP::WSDL::XSD::Typelib::Builtin::base64Binary; use SOAP::WSDL::XSD::Typelib::Builtin::boolean; use SOAP::WSDL::XSD::Typelib::Builtin::byte; use SOAP::WSDL::XSD::Typelib::Builtin::date; use SOAP::WSDL::XSD::Typelib::Builtin::dateTime; use SOAP::WSDL::XSD::Typelib::Builtin::decimal; use SOAP::WSDL::XSD::Typelib::Builtin::double; use SOAP::WSDL::XSD::Typelib::Builtin::duration; use SOAP::WSDL::XSD::Typelib::Builtin::ENTITY; use SOAP::WSDL::XSD::Typelib::Builtin::float; use SOAP::WSDL::XSD::Typelib::Builtin::gDay; use SOAP::WSDL::XSD::Typelib::Builtin::gMonth; use SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay; use SOAP::WSDL::XSD::Typelib::Builtin::gYear; use SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth; use SOAP::WSDL::XSD::Typelib::Builtin::hexBinary; use SOAP::WSDL::XSD::Typelib::Builtin::ID; use SOAP::WSDL::XSD::Typelib::Builtin::IDREF; use SOAP::WSDL::XSD::Typelib::Builtin::IDREFS; use SOAP::WSDL::XSD::Typelib::Builtin::int; use SOAP::WSDL::XSD::Typelib::Builtin::integer; use SOAP::WSDL::XSD::Typelib::Builtin::language; use SOAP::WSDL::XSD::Typelib::Builtin::list; use SOAP::WSDL::XSD::Typelib::Builtin::long; use SOAP::WSDL::XSD::Typelib::Builtin::Name; use SOAP::WSDL::XSD::Typelib::Builtin::NCName; use SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger; use SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN; use SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS; use SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger; use SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger; use SOAP::WSDL::XSD::Typelib::Builtin::normalizedString; use SOAP::WSDL::XSD::Typelib::Builtin::NOTATION; use SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger; use SOAP::WSDL::XSD::Typelib::Builtin::QName; use SOAP::WSDL::XSD::Typelib::Builtin::short; use SOAP::WSDL::XSD::Typelib::Builtin::string; use SOAP::WSDL::XSD::Typelib::Builtin::time; use SOAP::WSDL::XSD::Typelib::Builtin::token; use SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte; use SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt; use SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong; use SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort; 1; __END__ =pod =head1 NAME SOAP::WSDL::XSD::Typelib::Builtin - Built-in XML Schema datatypes =head1 DESCRIPTION The SOAP::WSDL::XSD::Typelib::Builtin hierarchy implements all builtin types from the XML schema specification. All XML schema derived types inherit from SOAP::WSDL::XSD::Typelib::Builtin::anyType. These basic type classes are most useful when used as element or simpleType base classes. Using SOAP::WSDL::XSD::Typelib::Builtin uses all of the builtin datatype classes. All builtin types feature common behaviour described below in L =head1 EXAMPLES my $bool = SOAP::WSDL::XSD::Typelib::Builtin::bool->new({ value => 0} ); print $bool; # prints "true" # implements # # package MySimpleType; use SOAP::WSDL::XSD::Typelib::Builtin; use SOAP::WSDL::XSD::Typelib::SimpleType; use base qw(SOAP::WSDL::XSD::Typelib::SimpleType SOAP::WSDL::XSD::Typelib::Builtin::list SOAP::WSDL::XSD::Typelib::Builtin::string ); 1; # somewhere else my $list = MySimpleType->new({ value => [ 'You', 'shall', 'overcome' ] }); print $list; # prints "You shall overcome" =head1 CLASS HIERARCHY This is the inheritance graph for builtin types. Types with [] marker describe types derived via the item in [] in the XML Schema specs. Derivation is implemented via multiple inheritance with the derivation method as first item in the base class list. anyType - anySimpleType - duration - dateTime - date - time - gYearMonth - gYear - gMonthDay - gDay - gMonth - boolean - base64Binary - hexBinary - float - decimal - integer - nonPositiveInteger - negativeInteger - nonNegativeInteger - positiveInteger - unsignedLong - unsignedInt - unsignedShort - unsignedByte - long - int - short - byte - double - anyURI - NOTATION - string - normalizedString - language - Name - NCName - ID - IDREF - IDREFS [list] - ENTITY - token - NMTOKEN - NMTOKENS [list] =head1 OVERLOADED OPERATORS Overloading is implemented via Class::Std's trait mechanism. The following behaviours apply: =over =item * string context All classes use the C method for stringification. =item * bool context All classes derived from anySimpleType return their value in bool context =item * numeric context The boolean class returns 0 or 1 in numeric context. decimal, float and double (and derived classes) return their value in numeric context. =item * arrayification (@{}) When accessed as a list ref, objects of all classes return a list ref with the object itself as single element. This is most useful for writing loops without additional conversions, especially in mini-languages found in templating systems or the like, which may not natively support converting to list refs. Instead of writing something like my $value = $complexType->get_ELEMENT; $value = ref $value eq 'ARRAY' ? $value : [ $value ]; for (@{ $value }) { ... } you can just write for (@{ $complexType->get_ELEMENT }) {...} Note that complexTypes with undef elements still return undef when accessing an undefined element, so when an element may be empty you still have to write something like: my $value = $complexType->get_ELEMENT(); if (defined $value) { for (@{ $value }) { ... } } =back =head1 Subclasses =head2 SOAP::WSDL::XSD::Typelib::Builtin::anyType Base class for all types =head2 SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType Base class for all simple types =head2 SOAP::WSDL::XSD::Typelib::Builtin::anyURI Type representing URIs =head2 SOAP::WSDL::XSD::Typelib::Builtin::boolean Represents boolean data. Serializes to "true" or "false". Everything true in perl and not "false" is deserialized as true. Returns true/false in boolean context. Returns 1 / 0 in numeric context. boolean objects have a special method for deleting their value, because calling C results in the value being set to false. $obj->delete_value(); =head2 SOAP::WSDL::XSD::Typelib::Builtin::byte 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 When setting dates before the beginning of the epoch (negative UNIX timestamp), you should use the XML date string format for setting dates. The behaviour of Date::Parse for dates before the epoch is system dependent. =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 fraction of seconds (nnnnnnn) part is optional. Fractions of seconds may be given with arbitrary precision The fraction of seconds part 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 decimal is the base of all non-float numbers =head2 SOAP::WSDL::XSD::Typelib::Builtin::double =head2 SOAP::WSDL::XSD::Typelib::Builtin::duration =head2 SOAP::WSDL::XSD::Typelib::Builtin::ENTITY =head2 SOAP::WSDL::XSD::Typelib::Builtin::float =head2 SOAP::WSDL::XSD::Typelib::Builtin::gDay =head2 SOAP::WSDL::XSD::Typelib::Builtin::gMonth =head2 SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay =head2 SOAP::WSDL::XSD::Typelib::Builtin::gYear =head2 SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth =head2 SOAP::WSDL::XSD::Typelib::Builtin::hexBinary =head2 SOAP::WSDL::XSD::Typelib::Builtin::ID =head2 SOAP::WSDL::XSD::Typelib::Builtin::IDREF =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 =head2 SOAP::WSDL::XSD::Typelib::Builtin::integer =head2 SOAP::WSDL::XSD::Typelib::Builtin::language =head2 SOAP::WSDL::XSD::Typelib::Builtin::list =head2 SOAP::WSDL::XSD::Typelib::Builtin::long =head2 SOAP::WSDL::XSD::Typelib::Builtin::Name =head2 SOAP::WSDL::XSD::Typelib::Builtin::NCName =head2 SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger =head2 SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger =head2 SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger =head2 SOAP::WSDL::XSD::Typelib::Builtin::normalizedString Tab, newline and carriage return characters are replaced by whitespace in set_value. =head2 SOAP::WSDL::XSD::Typelib::Builtin::NOTATION =head2 SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger =head2 SOAP::WSDL::XSD::Typelib::Builtin::QName =head2 SOAP::WSDL::XSD::Typelib::Builtin::short =head2 SOAP::WSDL::XSD::Typelib::Builtin::string String values are XML-escaped on serialization. The following characters are escaped: <, >, & =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 =head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt =head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong =head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort =head1 CAVEATS =over =item * set_value In contrast to Class::Std-generated mutators (setters), set_value does not return the last value. This is for speed reasons: SOAP::WSDL never needs to know the last value when calling set_calue, but calls it over and over again... =back =head1 BUGS AND LIMITATIONS =over =item * Thread safety SOAP::WSDL::XSD::Typelib::Builtin uses Class::Std::Fast::Storable which uses Class::Std. Class::Std is not thread safe, so SOAP::WSDL::XSD::Typelib::Builtin is neither. =item * XML Schema facets No facets are implemented yet. =back =head1 AUTHOR Replace whitespace by @ in e-mail address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Annotation.pm010064400017500001750000000006271361135215300173400ustar00scottscottpackage SOAP::WSDL::XSD::Annotation; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %appinfo_of :ATTR(:name :default<()>); # documentation provided by Base 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Element.pm010064400017500001750000000072151361135215300166170ustar00scottscottpackage SOAP::WSDL::XSD::Element; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # id provided by Base # name provided by Base # annotation provided by Base my %simpleType_of :ATTR(:name :default<()>); my %complexType_of :ATTR(:name :default<()>); my %facet_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); my %abstract_of :ATTR(:name :default<()>); my %block_of :ATTR(:name :default<()>); my %default_of :ATTR(:name :default<()>); my %final_of :ATTR(:name :default<()>); my %fixed_of :ATTR(:name :default<()>); my %form_of :ATTR(:name
:default<()>); my %maxOccurs_of :ATTR(:name :default<()>); my %minOccurs_of :ATTR(:name :default<()>); my %nillable_of :ATTR(:name :default<()>); my %ref_of :ATTR(:name :default<()>); my %substitutionGroup_of :ATTR(:name :default<()>); sub first_simpleType { my $result_ref = $simpleType_of{ ident shift }; return if not $result_ref; return $result_ref if (not ref $result_ref eq 'ARRAY'); return $result_ref->[0]; } sub first_complexType { my $result_ref = $complexType_of{ ident shift }; return if not $result_ref; return $result_ref if (not ref $result_ref eq 'ARRAY'); return $result_ref->[0]; } # serialize type instead... sub serialize { my ($self, $name, $value, $opt) = @_; my $type; my $typelib = $opt->{ typelib }; my %ns_map = %{ $opt->{ namespace } }; my $ident = ident $self; # abstract elements may only be serialized via ref - and then we have a # name... die "cannot serialize abstract element" if $abstract_of{ $ident } and not $name; # TODO: implement final and substitutionGroup - maybe never implement # substitutionGroup ? $name = $self->get_name() if not ($name); if ( $opt->{ qualify } ) { $opt->{ attributes } = [ ' xmlns="' . $self->get_targetNamespace .'"' ]; } # set default and fixed - fixed overrides everything, # default only empty (undefined) values if (not defined $value) { $value = $default_of{ ident $self } if $default_of{ ident $self }; } $value = $fixed_of{ ident $self } if $fixed_of{ ident $self }; # TODO check nillable and serialize empty data correctly # return if minOccurs is 0 and we have no value if (defined $minOccurs_of{ ident $self } and $minOccurs_of{ ident $self } == 0) { return q{} if not defined $value; } # handle direct simpleType and complexType here if ($type = $self->first_simpleType() ) { # simpleType return $type->serialize( $name, $value, $opt ); } elsif ($type = $self->first_complexType() ) { # complexType return $type->serialize( $name, $value, $opt ); } elsif (my $ref_name = $ref_of{ $ident }) { # ref my ($prefix, $localname) = split /:/ , $ref_name; my $ns = $ns_map{ $prefix }; $type = $typelib->find_element( $ns, $localname ); die "no element for ref $prefix:$localname" if (not $type); return $type->serialize( $name, $value, $opt ); } # lookup type my ($prefix, $localname) = split /:/ , $self->get_type(); my $ns = $ns_map{ $prefix }; $type = $typelib->find_type( $ns, $localname ); # safety check die "no type for $prefix:$localname $ns_map{$prefix}" if (not $type); return $type->serialize( $name, $value, $opt ); } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/SimpleType.pm010064400017500001750000000104741361135215300173220ustar00scottscottpackage SOAP::WSDL::XSD::SimpleType; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %length_of :ATTR(:name :default<[]>); my %minLength_of :ATTR(:name :default<[]>); my %maxLength_of :ATTR(:name :default<[]>); my %pattern_of :ATTR(:name :default<[]>); my %enumeration_of :ATTR(:name :default<[]>); my %whiteSpace_of :ATTR(:name :default<[]>); my %totalDigits_of :ATTR(:name :default<[]>); my %fractionDigits_of :ATTR(:name :default<[]>); my %minExclusive :ATTR(:name :default<[]>); my %minInclusive :ATTR(:name :default<[]>); my %maxExclusive :ATTR(:name :default<[]>); my %maxInclusive :ATTR(:name :default<[]>); my %fixed :ATTR(:name :default<[]>); my %annotation_of :ATTR(:name :default<()>); my %base_of :ATTR(:name :default<()>); my %itemType_of :ATTR(:name :default<()>); # TODO rename flavor to variety to be consistent with the XML Schema # specs - though flavor is the cooler name.. # set to restriction|list|union|enumeration my %flavor_of :ATTR(:name :default<()>); # for simpleType containing atomic simple types my %type_of :ATTR(:name :default<()>); sub get_simpleType; *get_simpleType = \&get_type; sub set_simpleType; *set_simpleType = \&set_type; sub get_variety; *get_variety = \&get_flavor; sub set_restriction { my $self = shift; my @attributes = @_; $self->set_flavor( 'restriction' ); for (@attributes) { next if (not $_->{ LocalName } eq 'base'); $self->set_base( $_->{ Value } ); } } sub set_list { my $self = shift; my @attributes = @_; $self->set_flavor( 'list' ); for (@attributes) { next if (not $_->{ LocalName } eq 'itemType'); $self->set_itemType( $_->{ Value } ); } } sub set_union { my $self = shift; my @attributes = @_; $self->set_flavor( 'union' ); for (@attributes) { next if (not $_->{ LocalName } eq 'memberTypes'); $self->set_base( [ split /\s/, $_->{ Value } ] ); } } sub serialize { my $self = shift; my $name = shift; my $value = shift; my $opt = shift; my $ident = ident $self; $opt->{ attributes } ||= []; $opt->{ indent } ||= q{}; return $self->_serialize_single($name, $value , $opt) if ( $flavor_of{ $ident } eq 'restriction' or $flavor_of{ $ident } eq 'union' or $flavor_of{ $ident } eq 'enumeration'); if ($flavor_of{ $ident } eq 'list' ) { $value ||= []; $value = [ $value ] if ( ref( $value) ne 'ARRAY' ); return $self->_serialize_single($name, join( q{ }, @{ $value } ), $opt); } } sub _serialize_single { my ($self, $name, $value, $opt) = @_; my $xml = ''; $xml .= $opt->{ indent } if ($opt->{ readable }); # add indentation $xml .= '<' . join ' ', $name, @{ $opt->{ attributes } }; if ( $opt->{ autotype }) { # reverse namespace by prefix hash my $ns = $self->get_targetNamespace(); # build a list of hash keys (eg '#default', 'tns') whose values match our namespace (eg 'urn:myNamespace') (my @possible_namespace_names) = grep { $opt->{ namespace }->{$_} eq $ns } keys %{ $opt->{ namespace } }; # put any '#default' option last @possible_namespace_names = sort { $a eq '#default' ? 1 : $b eq '#default' ? -1 : $a cmp $b } @possible_namespace_names; if( grep( $_ ne '#default', @possible_namespace_names ) > 1 or ! @possible_namespace_names ) { die "No prefix found for namespace $ns, or too many possible names: ``@possible_namespace_names''; there should be just one and maybe a '#default' entry"; } my $prefix = $possible_namespace_names[0]; $xml .= ' type="' . $prefix . ':' . $self->get_name() .'"'; } # nillabel ? return $xml .'/>' if not defined $value; $xml .= join q{}, '>' , $value , ''; $xml .= "\n" if ($opt->{ readable }); return $xml; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/AttributeGroup.pm010064400017500001750000000012621361135215300202020ustar00scottscottpackage SOAP::WSDL::XSD::AttributeGroup; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) # # id provided by Base # name provided by Base # annotation provided by Base my %ref_of :ATTR(:name :default<()>); # may be defined as atomic simpleType my %attribute_of :ATTR(:name :default<()>); my %attributeGroup_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Schema004075500017500001750000000000001361135364100160125ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Schema/Builtin.pm010064400017500001750000000055561361135215300200420ustar00scottscottpackage SOAP::WSDL::XSD::Schema::Builtin; use strict; use warnings; use Class::Std::Fast::Storable; use SOAP::WSDL::XSD::Schema; use SOAP::WSDL::XSD::Builtin; use base qw(SOAP::WSDL::XSD::Schema); our $VERSION = 3.004; # all builtin types - add validation (e.g. content restrictions) later... my %BUILTINS = ( 'anyType' => {}, 'anySimpleType' => {}, 'anyURI' => {}, 'boolean' => {}, 'base64Binary' => {}, 'byte' => {}, 'date' => {}, 'dateTime' => {}, 'decimal' => {}, 'double' => {}, 'duration' => {}, 'ENTITY' => {}, 'float' => {}, 'gDay' => {}, 'gMonth' => {}, 'gMonthDay' => {}, 'gYearMonth' => {}, 'gYear' => {}, 'hexBinary' => {}, 'ID' => {}, 'IDREF' => {}, 'IDREFS' => {}, 'int' => {}, 'integer' => {}, 'language' => {}, 'long' => {}, 'negativeInteger' => {}, 'nonPositiveInteger' => {}, 'nonNegativeInteger' => {}, 'normalizedString' => {}, 'Name' => {}, 'NCName' => {}, 'NMTOKEN' => {}, 'NOTATION' => {}, 'positiveInteger' => {}, 'QName' => {}, 'short' => {}, 'string' => {}, 'time' => {}, 'token' => {}, 'unsignedByte' => {}, 'unsignedInt' => {}, 'unsignedLong' => {}, 'unsignedShort' => {}, ); sub START { my $self = shift; my @args = @_; while (my ($name, $value) = each %BUILTINS ) { $self->push_type( SOAP::WSDL::XSD::Builtin->new({ name => $name, targetNamespace => 'http://www.w3.org/2001/XMLSchema', xmlns => { '#default' => 'http://www.w3.org/2001/XMLSchema', } } ) ); } return $self; } 1; =pod =head1 NAME SOAP:WSDL::XSD::Schema::Builtin - Provides builtin XML Schema datatypes for parsing WSDL =head1 DESCRIPTION Used internally by SOAP::WSDL's WSDL parser. See for SOAP::WSDL::XSD's builtin XML Schema datatypes. =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Builtin.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Schema/Builtin.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/TotalDigits.pm010064400017500001750000000006471361135215300174570ustar00scottscottpackage SOAP::WSDL::XSD::TotalDigits; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); my %fixed_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MinLength.pm010064400017500001750000000005611361135215300171100ustar00scottscottpackage SOAP::WSDL::XSD::MinLength; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Pattern.pm010064400017500001750000000005521361135215300166400ustar00scottscottpackage SOAP::WSDL::XSD::Pattern; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/ComplexType.pm010064400017500001750000000145461361135215300175040ustar00scottscottpackage SOAP::WSDL::XSD::ComplexType; use strict; use warnings; use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # id provided by Base # name provided by Base # annotation provided by Base my %length_of :ATTR(:name :default<[]>); my %minLength_of :ATTR(:name :default<[]>); my %maxLength_of :ATTR(:name :default<[]>); my %pattern_of :ATTR(:name :default<[]>); my %enumeration_of :ATTR(:name :default<[]>); my %whiteSpace_of :ATTR(:name :default<[]>); my %totalDigits_of :ATTR(:name :default<[]>); my %fractionDigits_of :ATTR(:name :default<[]>); my %minExclusive :ATTR(:name :default<[]>); my %minInclusive :ATTR(:name :default<[]>); my %maxExclusive :ATTR(:name :default<[]>); my %maxInclusive :ATTR(:name :default<[]>); my %attribute_of :ATTR(:name :default<()>); my %element_of :ATTR(:name :default<[]>); my %group_of :ATTR(:name :default<()>); my %variety_of :ATTR(:name :default<()>); my %base_of :ATTR(:name :default<()>); my %itemType_of :ATTR(:name :default<()>); my %abstract_of :ATTR(:name :default<()>); my %final_of :ATTR(:name :default<()>); my %mixed_of :ATTR(:name :default<()>); # default is false my %derivation_of :ATTR(:name :default<()>); # is set to simpleContent/complexContent my %content_model_of :ATTR(:name :default); sub get_flavor; *get_flavor = \&get_variety; sub push_element { my $self = shift; my $element = shift; if ($variety_of{ ident $self } eq 'all') { $element->set_minOccurs(0) if not defined ($element->get_minOccurs); $element->set_maxOccurs(1) if not defined ($element->get_maxOccurs); } elsif ($variety_of{ ident $self } eq 'sequence') { $element->set_minOccurs(1) if not defined ($element->get_minOccurs); $element->set_maxOccurs(1) if not defined ($element->get_maxOccurs); } push @{ $element_of{ ident $self } }, $element; } sub set_restriction { my $self = shift; my $element = shift; $variety_of{ ident $self } = 'restriction'; $derivation_of{ ident $self } = 'restriction'; $base_of{ ident $self } = $element->{ Value }; } sub set_extension { my $self = shift; my $element = shift; $variety_of{ ident $self } = 'extension'; $derivation_of{ ident $self } = 'extension'; $base_of{ ident $self } = $element->{ Value }; } sub init { my $self = shift; my @args = @_; $self->SUPER::init( @args ); } sub serialize { my ($self, $name, $value, $opt) = @_; $opt->{ indent } ||= q{}; $opt->{ attributes } ||= []; my $variety = $self->get_variety(); my $xml = ($opt->{ readable }) ? $opt->{ indent } : q{}; # add indentation if ( $opt->{ qualify } ) { $opt->{ attributes } = [ ' xmlns="' . $self->get_targetNamespace .'"' ]; delete $opt->{ qualify }; } $xml .= join q{ } , "<$name" , @{ $opt->{ attributes } }; delete $opt->{ attributes }; # don't propagate... if ( $opt->{ autotype }) { my $ns = $self->get_targetNamespace(); # reverse namespace by prefix hash # build a list of hash keys (eg '#default', 'tns') whose values match our namespace (eg 'urn:myNamespace') (my @possible_namespace_names) = grep { $opt->{ namespace }->{$_} eq $ns } keys %{ $opt->{ namespace } }; # put any '#default' option last @possible_namespace_names = sort { $a eq '#default' ? 1 : $b eq '#default' ? -1 : $a cmp $b } @possible_namespace_names; if( grep( $_ ne '#default', @possible_namespace_names ) > 1 or ! @possible_namespace_names ) { die "No prefix found for namespace $ns, or too many possible names: ``@possible_namespace_names''; there should be just one and maybe a '#default' entry"; } my $prefix = $possible_namespace_names[0]; $xml .= join q{}, " type=\"$prefix:", $self->get_name(), '" ' if ($self->get_name() ); } $xml .= '>'; $xml .= "\n" if ( $opt->{ readable } ); # add linebreak if ($self->schema) { if ($self->schema()->get_elementFormDefault() ne "qualified") { push @{$opt->{ attributes } }, q{xmlns=""} if ($self->get_targetNamespace() ne ""); } } if ( ($variety eq "sequence") or ($variety eq "all") ) { $opt->{ indent } .= "\t"; for my $element (@{ $self->get_element() }) { # resolve element ref # # Basic algorithm is like this: # If on serialization, we meet a element whose get_ref method # returns a true value, lookup the element from the # definitions instead, and serialize this element. # if (my $ref = $element->get_ref()) { $element = $opt->{ typelib }->find_element( $element->expand($ref) ); } # might be list - listify $value = [ $value ] if not ref $value eq 'ARRAY'; for my $single_value (@{ $value }) { my $element_value; if (blessed $single_value) { my $method = 'get_' . $element->get_name(); $element_value = $single_value->$method(); } else { $element_value = $single_value->{ $element->get_name() }; } $element_value = [ $element_value ] if not ref $element_value eq 'ARRAY'; $xml .= join q{} , map { $element->serialize( undef, $_, $opt ) } @{ $element_value }; } } $opt->{ indent } =~s/\t$//; } else { die "sorry, we just handle all and sequence types yet..."; } $xml .= $opt->{ indent } if ( $opt->{ readable } ); # add indentation $xml .= ''; $xml .= "\n" if ($opt->{ readable } ); # add linebreak return $xml; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MinExclusive.pm010064400017500001750000000005641361135215300176410ustar00scottscottpackage SOAP::WSDL::XSD::MinExclusive; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/FractionDigits.pm010064400017500001750000000005611361135215300201340ustar00scottscottpackage SOAP::WSDL::XSD::FractionDigits; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Attribute.pm010064400017500001750000000017651361135215300171750ustar00scottscottpackage SOAP::WSDL::XSD::Attribute; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # Content: (annotation?, (simpleType?)) # # id provided by Base # name provided by Base # annotation provided by Base my %default_of :ATTR(:name :default<()>); my %fixed_of :ATTR(:name :default<()>); my %form_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); my %use_of :ATTR(:name :default<()>); my %ref_of :ATTR(:name :default<()>); # may be defined as atomic simpleType my %simpleType_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Group.pm010064400017500001750000000017321361135215300163200ustar00scottscottpackage SOAP::WSDL::XSD::Group; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # # # . . . # # # # # # # # # # # # # # # my %ref_of :ATTR(:name :default<()>); my %maxOccurs_of :ATTR(:name :default<()>); my %minOccurs_of :ATTR(:name :default<()>); my %annotation_of :ATTR(:name :default<()>); my %element_of :ATTR(:name :default<()>); my %group_of :ATTR(:name :default<()>); my %variety_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Enumeration.pm010064400017500001750000000005621361135215300175120ustar00scottscottpackage SOAP::WSDL::XSD::Enumeration; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Schema.pm010064400017500001750000000046261361135215300164310ustar00scottscottpackage SOAP::WSDL::XSD::Schema; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # child elements my %attributeGroup_of :ATTR(:name :default<[]>); my %attribute_of :ATTR(:name :default<[]>); my %element_of :ATTR(:name :default<[]>); my %group_of :ATTR(:name :default<[]>); my %type_of :ATTR(:name :default<[]>); # attributes my %attributeFormDefault_of :ATTR(:name :default); my %blockDefault_of :ATTR(:name :default<()>); my %elementFormDefault_of :ATTR(:name :default); my %finalDefault_of :ATTR(:name :default<()>); my %version_of :ATTR(:name :default<()>); # id # name # targetNamespace inherited from Base # xmlns # # attributeFormDefault = (qualified | unqualified) : unqualified # blockDefault = (#all | List of (extension | restriction | substitution)) : '' # elementFormDefault = (qualified | unqualified) : unqualified # finalDefault = (#all | List of (extension | restriction | list | union)) : '' # id = ID # targetNamespace = anyURI # version = token # xml:lang = language # # # alias type with all variants # AUTOMETHOD is WAY too slow.. { no strict qw/refs/; for my $name (qw(simpleType complexType) ) { *{ "set_$name" } = \&set_type; *{ "get_$name" } = \&get_type; *{ "push_$name" } = \&push_type; *{ "find_$name" } = \&find_type; } } sub push_type { # use $_[n] for performance - # we're called on each and every type inside WSDL push @{ $type_of{ ident $_[0]} }, $_[1]; } sub find_element { my ($self, @args) = @_; my @found_at = grep { $_->get_targetNamespace() eq $args[0] && # warn $_->get_name() . " default NS:" . $_->get_xmlns()->{'#default'} . "\n"; # $_->get_xmlns()->{'#default'} eq $args[0] && $_->get_name() eq $args[1] } @{ $element_of{ ident $self } }; return $found_at[0]; } sub find_type { my ($self, @args) = @_; my @found_at = grep { $_->get_targetNamespace() eq $args[0] && # $_->get_xmlns()->{'#default'} eq $args[0] && $_->get_name() eq $args[1] } @{ $type_of{ ident $self } }; return $found_at[0]; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Builtin.pm010064400017500001750000000020121361135215300166220ustar00scottscottpackage SOAP::WSDL::XSD::Builtin; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # only used in SOAP::WSDL - will be obsolete once SOAP::WSDL uses the # generative approach, too 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_of = reverse %{ $opt->{ namespace } }; my $prefix = $prefix_of{ $ns } || die 'No prefix found for namespace '. $ns; $xml .= ' type="' . $prefix . ':' . $self->get_name() . '"'; } if (defined $value) { $xml .= '>'; $xml .= "$value"; $xml .= '' ; } else { $xml .= '/>'; } $xml .= "\n" if ($opt->{ readable }); return $xml; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/WhiteSpace.pm010064400017500001750000000005551361135215300172620ustar00scottscottpackage SOAP::WSDL::XSD::WhiteSpace; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/Length.pm010064400017500001750000000005561361135215300164500ustar00scottscottpackage SOAP::WSDL::XSD::Length; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MaxInclusive.pm010064400017500001750000000005641361135215300176350ustar00scottscottpackage SOAP::WSDL::XSD::MaxInclusive; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MinInclusive.pm010064400017500001750000000005641361135215300176330ustar00scottscottpackage SOAP::WSDL::XSD::MinInclusive; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MaxLength.pm010064400017500001750000000006441361135215300171140ustar00scottscottpackage SOAP::WSDL::XSD::MaxLength; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); my %fixed_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/XSD/MaxExclusive.pm010064400017500001750000000005641361135215300176430ustar00scottscottpackage SOAP::WSDL::XSD::MaxExclusive; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; # # id provided by Base # name provided by Base # annotation provided by Base # may be defined as atomic simpleType my %value_of :ATTR(:name :default<()>); 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/Deserializer004075500017500001750000000000001361135364200165775ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Deserializer/XSD.pm010064400017500001750000000071001361135215200176400ustar00scottscottpackage SOAP::WSDL::Deserializer::XSD; use strict; use warnings; use Class::Std::Fast::Storable; use SOAP::WSDL::SOAP::Typelib::Fault11; use SOAP::WSDL::Expat::MessageParser; our $VERSION = 3.004; my %class_resolver_of :ATTR(:name :default<()>); my %strict_of :ATTR(:get :init_arg :default<1>); my %parser_of :ATTR(); sub set_strict { undef $parser_of{${$_[0]}}; $strict_of{${$_[0]}} = $_[1]; } sub BUILD { my ($self, $ident, $args_of_ref) = @_; # ignore all options except 'class_resolver' for (keys %{ $args_of_ref }) { next if $_ eq 'strict'; next if $_ eq 'class_resolver'; delete $args_of_ref->{ $_ }; } } sub deserialize { my ($self, $content) = @_; $parser_of{ ${ $self } } = SOAP::WSDL::Expat::MessageParser->new({ strict => $strict_of{ ${ $self } } }) if not $parser_of{ ${ $self } }; $parser_of{ ${ $self } }->class_resolver( $class_resolver_of{ ${ $self } } ); $content =~ s{^<\?xml version="1.0" *\?>}{}; # XML::Parser::Expat apparently doesn't like this. eval { $parser_of{ ${ $self } }->parse_string( $content ) }; if ($@) { return $self->generate_fault({ code => 'SOAP-ENV:Server', role => 'urn:localhost', message => "Error deserializing message: $@. \n" . "Message was: \n$content" }); } return ( $parser_of{ ${ $self } }->get_data(), $parser_of{ ${ $self } }->get_header() ); } sub generate_fault { my ($self, $args_from_ref) = @_; return SOAP::WSDL::SOAP::Typelib::Fault11->new({ faultcode => $args_from_ref->{ code } || 'SOAP-ENV:Client', faultactor => $args_from_ref->{ role } || 'urn:localhost', faultstring => $args_from_ref->{ message } || "Unknown error" }); } 1; __END__ =head1 NAME SOAP::WSDL::Deserializer::XSD - Deserializer SOAP messages into SOAP::WSDL::XSD::Typelib:: objects =head1 DESCRIPTION Default deserializer for SOAP::WSDL::Client and interface classes generated by SOAP::WSDL. Converts SOAP messages to SOAP::WSDL::XSD::Typlib:: based objects. Needs a class_resolver typemap either passed by the generated interface or user-provided. SOAP::WSDL::Deserializer classes implement the API described in L. =head1 USAGE Usually you don't need to do anything to use this package - it's the default deserializer for SOAP::WSDL::Client and interface classes generated by SOAP::WSDL. If you want to use the XSD serializer from SOAP::WSDL, set the outputtree() property and provide a class_resolver. =head1 OPTIONS =over =item * strict Enables/disables strict XML processing. Strict processing is enabled by default. To disable strict XML processing pass the following to the constructor or use the C method: strict => 0 =back =head1 METHODS =head2 deserialize Deserializes the message. =head2 generate_fault Generates a L object and returns it. =head2 set_strict Enable/disable strict XML parsing. Default is enabled. =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: XSD.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Deserializer/SOM.pm010064400017500001750000000067471361135215200176600ustar00scottscottpackage SOAP::WSDL::Deserializer::SOM; use strict; use warnings; our $VERSION = 3.004; our @ISA; eval { require SOAP::Lite; push @ISA, 'SOAP::Deserializer'; } or die "Cannot load SOAP::Lite. Cannot deserialize to SOM object without SOAP::Lite. Please install SOAP::Lite."; sub deserialize { my $self = shift; my $result = eval { $self->SUPER::deserialize(@_) }; if ($@) { return SOAP::Fault->new( faultactor => 'SOAP-ENV:Server', faultstring => $@, ); } return $result; } sub generate_fault { my ($self, $args_from_ref) = @_; # code, message, detail, actor die SOAP::Fault->new( faultcode => $args_from_ref->{ code }, faultstring => $args_from_ref->{ message }, faultactor => $args_from_ref->{ role }, ); } 1; __END__ =head1 NAME SOAP::WSDL::Deserializer::SOM - Deserializer SOAP messages into SOM objects =head1 SYNOPSIS use SOAP::WSDL; use SOAP::WSDL::Deserializer::SOM; use SOAP::WSDL::Factory::Deserializer; SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ ); =head1 DESCRIPTION Deserializer for creating SOAP::Lite's SOM object as result of a SOAP call. This package is here for two reasons: =over =item * Compatibility You don't have to change the rest of your SOAP::Lite based app when switching to SOAP::WSDL, but can just use SOAP::WSDL::Deserializer::SOM to get back the same objects as you were used to. =item * Completeness SOAP::Lite covers much more of the SOAP specification than SOAP::WSDL. SOAP::WSDL::Deserializer::SOM can be used for content which cannot be deserialized by L. This may be XML including mixed content, attachements and other XML data not (yet) handled by L. =back SOAP::WSDL::Deserializer::SOM is a subclass of L from the L package. =head1 METHODS =head2 deserialize Deserializes a XML sting into a SOAP::SOM object. Returns a SOAP::Fault object on deserialization errors. =head2 generate_fault Dies with a SOAP::Fault object. =head1 USAGE SOAP::WSDL::Deserializer will not autoregister itself - to use it for a particular SOAP version just use the following lines: my $soap_version = '1.1'; # or '1.2', further versions may appear. use SOAP::WSDL::Deserializer::SOM; use SOAP::WSDL::Factory::Deserializer; SOAP::WSDL::Factory::Deserializer->register( $soap_version, __PACKAGE__ ); =head1 DIFFERENCES FROM OTHER CLASSES =head2 Differences from SOAP::Lite =over =item * No on_fault handler You cannot specify what to do when an error occurs - SOAP::WSDL will return a SOAP::Fault object on transport errors. =back =head2 Differences from other SOAP::WSDL::Deserializer classes =over =item * generate_fault SOAP::WSDL::Deserializer::SOM will die with a SOAP::Fault object on calls to generate_fault. This also means that a SOAP::Fault may be thrown as exception when using =back =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: SOM.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Deserializer/Hash.pm010064400017500001750000000071031361135215200200700ustar00scottscottpackage SOAP::WSDL::Deserializer::Hash; use strict; use warnings; use Class::Std::Fast::Storable; use SOAP::WSDL::SOAP::Typelib::Fault11; use SOAP::WSDL::Expat::Message2Hash; use SOAP::WSDL::Factory::Deserializer; SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ ); our $VERSION = 3.004; sub BUILD { my ($self, $ident, $args_of_ref) = @_; # ignore all options for (keys %{ $args_of_ref }) { delete $args_of_ref->{ $_ } } } sub deserialize { my ($self, $content) = @_; my $parser = SOAP::WSDL::Expat::Message2Hash->new(); eval { $parser->parse_string( $content ) }; if ($@) { die $self->generate_fault({ code => 'soap:Server', role => 'urn:localhost', message => "Error deserializing message: $@. \n" . "Message was: \n$content" }); } return $parser->get_data(); } sub generate_fault { my ($self, $args_from_ref) = @_; return SOAP::WSDL::SOAP::Typelib::Fault11->new({ faultcode => $args_from_ref->{ code } || 'SOAP-ENV:Client', faultactor => $args_from_ref->{ role } || 'urn:localhost', faultstring => $args_from_ref->{ message } || "Unknown error" }); } 1; =head1 NAME SOAP::WSDL::Deserializer::Hash - Deserializer SOAP messages into perl hash refs =head1 SYNOPSIS use SOAP::WSDL; use SOAP::WSDL::Deserializer::Hash; =head1 DESCRIPTION Deserializer for creating perl hash refs as result of a SOAP call. =head2 Output structure The XML structure is converted into a perl data structure consisting of hash and or list references. List references are used for holding array data. SOAP::WSDL::Deserializer::Hash creates list references always at the maximum depth possible. Examples: XML: 1 1 Perl: { MyDataArray => { MyData => [ 1, 1 ] } } XML: 1/MyData> 1/MyData> Perl: { MyDataArray => { MyData => [ { int => 1 }, { int => 1 } ] } } List reference creation is triggered by the second occurrence of an element. XML Array types with one element only will not be represented as list references. =head1 USAGE All you need to do is to use SOAP::WSDL::Deserializer::Hash. SOAP::WSDL::Deserializer::Hash autoregisters itself for SOAP1.1 messages You may register SOAP::WSDLDeserializer::Hash for other SOAP Versions by calling SOAP::Factory::Deserializer->register('1.2', SOAP::WSDL::Deserializer::Hash) =head1 Limitations =over =item * Namespaces All namespaces are ignored. =item * XML attributes All XML attributes are ignored. =back =head2 Differences from other SOAP::WSDL::Deserializer classes =over =item * generate_fault SOAP::WSDL::Deserializer::Hash will die with a SOAP::WSDL::Fault11 object when a parse error appears =back =head1 METHODS =head2 deserialize Deserializes the message. =head2 generate_fault Generates a L object and returns it. =head1 LICENSE AND COPYRIGHT Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Hash.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/Hash.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Types.pm010064400017500001750000000023121361135215300156650ustar00scottscottpackage SOAP::WSDL::Types; use strict; use warnings; use SOAP::WSDL::XSD::Schema::Builtin; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %schema_of :ATTR(:name :default<[]>); sub START { my ($self, $ident, $args_of) = @_; $self->push_schema( SOAP::WSDL::XSD::Schema::Builtin->new() ); return $self; } sub find_type { my ($self, $ns, $name) = @_; ($ns, $name) = @{ $ns } if ref $ns; # allow passing list refs foreach my $schema (@{ $schema_of{ ident $self } }) { my $type = $schema->find_type($ns, $name); return $type if $type; } return; } sub find_attribute { my ($self, $ns, $name) = @_; ($ns, $name) = @{ $ns } if ref $ns; # allow passing list refs foreach my $schema (@{ $schema_of{ ident $self } }) { my $type = $schema->find_attribute($ns, $name); return $type if $type; } return; } sub find_element { my ($self, $ns, $name) = @_; ($ns, $name) = @{ $ns } if ref $ns; # allow passing list refs foreach my $schema (@{ $schema_of{ ident $self } }) { my $type = $schema->find_element($ns, $name); return $type if $type; } return; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/PortType.pm010064400017500001750000000010471361135215300163530ustar00scottscottpackage SOAP::WSDL::PortType; use strict; use warnings; use Class::Std::Fast::Storable; use List::Util; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %operation_of :ATTR(:name :default<()>); # #=head2 find_operation # #$port_type->find_operation($namespace, $name) # #Returns the PortType's operation object matching the given namespace and #name # sub find_operation { return List::Util::first { ( $_->get_targetNamespace() eq $_[1] ) && ( $_->get_name() eq $_[2] ) } @{ $operation_of{ ${ $_[0] } } }; }; 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/Definitions.pm010064400017500001750000000064421361135215300170440ustar00scottscottpackage SOAP::WSDL::Definitions; use strict; use warnings; use List::Util qw(first); use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %types_of :ATTR(:name :default<[]>); my %message_of :ATTR(:name :default<[]>); my %portType_of :ATTR(:name :default<[]>); my %binding_of :ATTR(:name :default<[]>); my %service_of :ATTR(:name :default<[]>); my %namespace_of :ATTR(:name :default<()>); # must be attr for Class::Std::Fast::Storable #my %attributes_of :ATTR(); my %attributes_of = ( binding => \%binding_of, message => \%message_of, portType => \%portType_of, service => \%service_of, ); # Function factory - we could be writing this method for all %attribute # keys, too, but that's just C&P (eehm, Copy & Paste...) BLOCK: { foreach my $method(keys %attributes_of ) { no strict qw/refs/; ## no critic ProhibitNoStrict *{ "find_$method" } = sub { my ($self, @args_from) = @_; @args_from = @{ $args_from[0] } if ref $args_from[0] eq 'ARRAY'; return first { $_->get_targetNamespace() eq $args_from[0] && $_->get_name() eq $args_from[1] } @{ $attributes_of{ $method }->{ ident $self } }; }; } } 1; =pod =head1 NAME SOAP::WSDL::Definitions - model a WSDL EdefinitionsE element =head1 DESCRIPTION =head1 METHODS =head2 first_service get_service set_service push_service Accessors/Mutators for accessing / setting the EserviceE child element(s). =head2 find_service Returns the service matching the namespace/localname pair passed as arguments. my $service = $wsdl->find_service($namespace, $localname); =head2 first_binding get_binding set_binding push_binding Accessors/Mutators for accessing / setting the EbindingE child element(s). =head2 find_binding Returns the binding matching the namespace/localname pair passed as arguments. my $binding = $wsdl->find_binding($namespace, $localname); =head2 first_portType get_portType set_portType push_portType Accessors/Mutators for accessing / setting the EportTypeE child element(s). =head2 find_portType Returns the portType matching the namespace/localname pair passed as arguments. my $portType = $wsdl->find_portType($namespace, $localname); =head2 first_message get_message set_message push_message Accessors/Mutators for accessing / setting the EmessageE child element(s). =head2 find_message Returns the message matching the namespace/localname pair passed as arguments. my $message = $wsdl->find_message($namespace, $localname); =head2 first_types get_types set_types push_types Accessors/Mutators for accessing / setting the EtypesE child element(s). =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Definitions.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Definitions.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Client.pm010064400017500001750000000316151361135215300160070ustar00scottscottpackage SOAP::WSDL::Client; use strict; use warnings; use Carp; use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); use SOAP::WSDL::Factory::Deserializer; use SOAP::WSDL::Factory::Serializer; use SOAP::WSDL::Factory::Transport; use SOAP::WSDL::Expat::MessageParser; our $VERSION = 3.004; my %class_resolver_of :ATTR(:name :default<()>); my %no_dispatch_of :ATTR(:name :default<()>); my %prefix_of :ATTR(:name :default<()>); my %outputxml_of :ATTR(:name :default<()>); my %transport_of :ATTR(:name :default<()>); my %endpoint_of :ATTR(:name :default<()>); my %soap_version_of :ATTR(:get :init_attr :default<1.1>); my %on_action_of :ATTR(:name :default<()>); my %content_type_of :ATTR(:name :default); #/#trick editors my %encoding_of :ATTR(:name :default); my %serializer_of :ATTR(:name :default<()>); my %deserializer_of :ATTR(:name :default<()>); my %deserializer_args_of :ATTR(:name :default<{}>); sub BUILD { my ($self, $ident, $attrs_of_ref) = @_; if (exists $attrs_of_ref->{ proxy }) { $self->set_proxy( $attrs_of_ref->{ proxy } ); delete $attrs_of_ref->{ proxy }; } return; } sub get_proxy { ## no critic RequireArgUnpacking return $_[0]->get_transport(); } sub set_proxy { my ($self, @args_from) = @_; my $ident = ${ $self }; # remember old value to return it later - Class::Std does so, too my $old_value = $transport_of{ $ident }; # accept both list and list ref args @args_from = @{ $args_from[0] } if ref $args_from[0]; # remember endpoint $endpoint_of{ $ident } = $args_from[0]; # set transport - SOAP::Lite works similar... $transport_of{ $ident } = SOAP::WSDL::Factory::Transport ->get_transport( @args_from ); return $old_value; } sub set_soap_version { my $ident = ${ $_[0] }; # remember old value to return it later - Class::Std does so, too my $soap_version = $soap_version_of{ $ident }; # re-setting the soap version invalidates the # serializer object delete $serializer_of{ $ident }; delete $deserializer_of{ $ident }; $soap_version_of{ $ident } = $_[1]; return $soap_version; } # Mimic SOAP::Lite's behaviour for getter/setter routines SUBFACTORY: { for (qw(class_resolver no_dispatch outputxml proxy prefix)) { my $setter = "set_$_"; my $getter = "get_$_"; no strict qw(refs); ## no critic ProhibitNoStrict *{ $_ } = sub { my $self = shift; if (@_) { $self->$setter(@_); return $self; } return $self->$getter() }; } } sub call { my ($self, $method, @data_from) = @_; my $ident = ${ $self }; # the only valid idiom for calling a method with both a header and a body # is # ->call($method, $body_ref, $header_ref); # # These other idioms all assume an empty header: # ->call($method, %body_of); # %body_of is a hash # ->call($method, $body); # $body is a scalar my ($data, $header) = ref $data_from[0] ? ($data_from[0], $data_from[1] ) : (@data_from>1) ? ( { @data_from }, undef ) : ( $data_from[0], undef ); # get operation name and soap_action my ($operation, $soap_action) = (ref $method eq 'HASH') ? ( $method->{ operation }, $method->{ soap_action } ) : (blessed $data && $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType')) ? ( $method , (join q{/}, $data->get_xmlns(), $method) ) : ( $method, q{} ); $serializer_of{ $ident } ||= SOAP::WSDL::Factory::Serializer->get_serializer({ soap_version => $self->get_soap_version(), }); my $envelope = $serializer_of{ $ident }->serialize({ method => $operation, body => $data, header => $header, options => {prefix => $prefix_of{ $ident }}, }); return $envelope if $self->no_dispatch(); # always quote SOAPAction header. # WS-I BP 1.0 R1109 if ($soap_action) { $soap_action =~s{\A(:?"|')?}{"}xms; $soap_action =~s{(:?"|')?\Z}{"}xms; } else { $soap_action = q{""}; } # get response via transport layer. # Normally, SOAP::Lite's transport layer is used, though users # may provide their own. my $transport = $self->get_transport(); my $response = $transport->send_receive( endpoint => $self->get_endpoint(), content_type => $content_type_of{ $ident }, encoding => $encoding_of{ $ident }, envelope => $envelope, action => $soap_action, # on_receive_chunk => sub {} # optional, may be used for parsing large responses as they arrive. ); return $response if ($outputxml_of{ $ident } ); # get deserializer use Data::Dumper; $deserializer_of{ $ident } ||= SOAP::WSDL::Factory::Deserializer->get_deserializer({ soap_version => $soap_version_of{ $ident }, %{ $deserializer_args_of{ $ident } }, }); # set class resolver if serializer supports it $deserializer_of{ $ident }->set_class_resolver( $class_resolver_of{ $ident } ) if ( $deserializer_of{ $ident }->can('set_class_resolver') ); # Try deserializing response - there may be some, # even if transport did not succeed (got a 500 response) if ( $response ) { # as our faults are false, returning a success marker is the only # reliable way of determining whether the deserializer succeeded. # Custom deserializers may return an empty list, or undef, # and $@ is not guaranteed to be undefined. my ($success, $result_body, $result_header) = eval { (1, $deserializer_of{ $ident }->deserialize( $response )); }; if (defined $success) { return wantarray ? ($result_body, $result_header) : $result_body; } elsif (blessed $@) { #}&& $@->isa('SOAP::WSDL::SOAP::Typelib::Fault11')) { return $@; } else { return $deserializer_of{ $ident }->generate_fault({ code => 'soap:Server', role => 'urn:localhost', message => "Error deserializing message: $@. \n" . "Message was: \n$response" }); } }; # if we had no success (Transport layer error status code) # or if transport layer failed if ( ! $transport->is_success() ) { # generate & return fault if we cannot serialize response # or have none... return $deserializer_of{ $ident }->generate_fault({ code => 'soap:Server', role => 'urn:localhost', message => 'Error sending / receiving message: ' . $transport->message() }); } } ## end sub call 1; __END__ =pod =head1 NAME SOAP::WSDL::Client - SOAP::WSDL's SOAP Client =head1 SYNOPSIS use SOAP::WSDL::Client; my $soap = SOAP::WSDL::Client->new({ proxy => 'http://www.example.org/webservice/test' }); $soap->call( \%method, $body, $header); =head1 METHODS =head2 call $soap->call( \%method, \@parts ); %method is a hash with the following keys: Name Description ---------------------------------------------------- operation operation name soap_action SOAPAction HTTP header to use style Operation style. One of (document|rpc) use SOAP body encoding. One of (literal|encoded) The style and use keys have no influence yet. @parts is a list containing the elements of the message parts. For backward compatibility, call may also be called as below: $soap->call( $method, \@parts ); In this case, $method is the SOAP operation name, and the SOAPAction header is guessed from the first part's namespace and the operation name (which is mostly correct, but may fail). Operation style and body encoding are assumed to be document/literal =head2 Configuration methods =head3 outputxml $soap->outputxml(1); When set, call() returns the raw XML of the SOAP Envelope. =head3 set_content_type $soap->set_content_type('application/xml; charset: utf8'); Sets the content type and character encoding. You probably should not use a character encoding different from utf8: SOAP::WSDL::Client will not convert the request into a different encoding (yet). To leave out the encoding, just set the content type without appending charset like this: $soap->set_content_type('text/xml'); Default: text/xml; charset: utf8 =head3 set_prefix $soap->set_prefix('ns2'); If set, alters the serialization of the request XML such that the supplied value is used as a namespace prefix for SOAP method calls. By way of example, the default XML serialization returns something like this: 12345 If the sample set_prefix() call above is used prior to calling your SOAP method, the XML serialization returns this instead: 12345 This is useful in cases where, for instance, one is communicating with a JAX L webservice, which tends to understand the latter but not the former. Note that this implementation is currently limited to a single additional namespace; if you require multiple custom namespaces, you should probably look into creating your own serializer. =head2 Features different from SOAP::Lite SOAP::WSDL does not aim to be a complete replacement for SOAP::Lite - the SOAP::Lite module has its strengths and weaknesses and SOAP::WSDL is designed as a cure for the weakness of little WSDL support - nothing more, nothing less. Nonetheless SOAP::WSDL mimics part of SOAP::Lite's API and behaviour, so SOAP::Lite users can switch without looking up every method call in the documentation. A few things are quite different from SOAP::Lite, though: =head3 SOAP request data SOAP request data may either be given as message object, or as a hash ref (in which case it will automatically be encoded into a message object). =head3 Return values The result from call() is not a SOAP::SOM object, but a message object. Message objects' classes may be generated from WSDL definitions automatically - see SOAP::WSDL::Generator::Typelib on how to generate your own WSDL based message class library. =head3 Fault handling SOAP::WSDL::Client returns a fault object on errors, even on transport layer errors. The fault object is a SOAP1.1 fault object of the following C. SOAP::WSDL::SOAP::Typelib::Fault11 objects are false in boolean context, so you can just do something like: my $result = $soap->call($method, $data); if ($result) { # handle result } else { die $result->faultstring(); } =head3 outputxml SOAP::Lite returns only the content of the SOAP body when outputxml is set to true. SOAP::WSDL::Client returns the complete XML response. =head3 Auto-Dispatching SOAP::WSDL::Client B support auto-dispatching. This is on purpose: You may easily create interface classes by using SOAP::WSDL::Client and implementing something like sub mySoapMethod { my $self = shift; $soap_wsdl_client->call( mySoapMethod, @_); } You may even do this in a class factory - see L for creating such interfaces. =head1 TROUBLESHOOTING =head2 Accessing protected web services Accessing protected web services is very specific for the transport backend used. In general, you may pass additional arguments to the set_proxy method (or a list ref of the web service address and any additional arguments to the new method's I argument). Refer to the appropriate transport module for documentation. =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Client.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual004075500017500001750000000000001361135364200153725ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/Serializer.pod010064400017500001750000000010621361134420300202530ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::Serializer - Serializer classes =head1 SERIALIZER CLASSES Serializer classes convert perl data structures to XML. SOAP::WSDL comes with one builtin serializer class: L. =head1 WRITING YOUR OWN SERIALIZER See L. =head1 LICENSE Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/FAQ.pod010064400017500001750000000123031361134503300165530ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::FAQ - Frequently Asked Questions (and answers) =head1 Development status =head2 Can I use SOAP::WSDL in a production environment? Yes. SOAP::WSDL is used in production environments. You should - as always - apply common sense and take appropriate safety measures, especially if running SOAP::WSDL as a server. =head2 Can I throw the WSDL away after generating? Please don't. Future versions of SOAP::WSDL may require you to re-generate interfaces in order to use them. =head1 SOAP/WSDL Version and message styles =head2 Which SOAP / WSDL versions does SOAP::WSDL support? SOAP1.1 and WSDL1.1. SOAP1.2 and WSDL2 are not supported yet. =head2 Which SOAP message Styles are supported? document/literal. The message / encoding styles rpc/encoded and rpc/literal are not supported (rpc/literal is hardly used). rpc/literal is not implemented yet. Unfortunately, SOAP::WSDL can't even parse many rpc/encoded WSDL definitions, and thus cannot inform you about unsupported message styles in some situations. =head1 Aren't rpc variants bad anyway? No. They can be as well-defined and useful as the document/literal variant. The difference between rpc and document is that rpc SOAP messages have an additional container named after the remote procedure called. rpc/literal is RPC with named parameters, whereas rpc/encoded corresponds to positional parameters. rpc/encoded is prohibited by the WS-I Basic Profile. However, rpc/encoded is still popular, especially for scripting languages like perl, python or php. You should probably use L for rpc/encoded web services. All the document/rpc literal/encoded discussion will cede with WSDL2.0: These variants are dropped in favour of an extensible operation style mechanism. =head1 XML Parsing / Generation =head2 Does SOAP::WSDL support namespaces? Well, sort of. SOAP::WSDL can use WSDL definitions containing namespaces, and emits SOAP messages with namespace information. Its SOAP message parser however, is not namespace sensitive but uses the pre-shared information from the WSDL for looking up what each XML node means. SOAP::WSDL can parse SOAP messages including namespace information up to the point where equally named elements from different namespaces may appear at the same position. This is a long-standing feature request and will eventually be resolved. =head2 Validation =head3 Does SOAP::WSDL perform XML Schema Validation? No, SOAP::WSDL does not perform XML Schema Validation. It does, however, enforce the correct structure on both XML and perl data. Occurrence, ordering, value-spaces, and identity constraints are not checked. =head3 Does SOAP::WSDL perform XML Validation? No, SOAP::WSDL does not perform XML Validation (that is, validation against a DTD). WS-I prohibits the use of DTDs in WSDL definitions. =head3 Isn't validation required for XML? No. The XML Specification does not require validation from XML processors. It states how validating and non-validating parsers must react on errors. Note: Validation in the context of (only) XML actually means DTD validation. =head3 And doesn't XML Schema require validation? The XML Schema specification requires conformant XML Schema processors to be able to validate XML Schema constraints. SOAP::WSDL is not a conformant XML Schema processor in this sense, as it does not validate all XML Schema constraints. =head3 And does SOAP require XML Schema Validation? No. The SOAP1.1 note does not say anything about validation. The SOAP1.2. specification explicitly states that XML Schema validation is not required for the SOAP envelope, and that applications may decide whether they need XML Schema Validation for the SOAP payload or not. The WSDL 1.1. specification does not mandate XML Schema validation. It does actually not even mandate the use of XML Schema for type definitions. =head2 Can SOAP::WSDL parse SOAP message fragments? No. SOAP::WSDL can parse neither well-formed nor not-well-formed SOAP message chunks. =head1 Persistence =head2 Can I use Storable to freeze/thaw SOAP::WSDL's objects? You can freeze almost all of SOAP::WSDL's objects. The only exceptions are the objects used in parsing WSDL definitions itself - they cannot be frozen. Note that freezing/thawing inside-out objects comes with a performance penalty and is at around the speed of XML generation/parsing. =head1 Performance and memory consumption =head2 How fast is SOAP::WSDL? As of this writing, SOAP::WSDL is the fastest SOAP Client toolkit for perl available on CPAN. There are no published server benchmarks yet. If you need extra speed you can try SOAP::WSDL_XS available from SOAP::WSDL's subversion repository at: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL_XS/trunk Note however that SOAP::WSDL_XS is not very mature yet and only suitable for use in trusted environments - you definitely should not use it on a public internet SOAP server yet. Note further that SOAP::WSDL's inside-out objects come with a big performance penalty when freezing/thawing them with Storable. =head2 There's a lot of perl modules generated. Don't they eat up all my memory? SOAP::WSDL usually uses a bit more memory than SOAP::Lite, but less than XML::Compile. Test if in question. =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/Glossary.pod010064400017500001750000000055711361134503300177600ustar00scottscott=head1 NAME SOAP::WSDL::Manual::Glossary - Those acronyms and stuff =head1 Glossary =head2 web service Web services are RPC (Remote Procedure Call) interfaces accessible via some internet protocol, typically via HTTP(S). =head2 SOAP SOAP is (was - since 1.2 the name "SOAP" has no meaning any more) an acronym for Simple Object Access Protocol. SOAP is a W3C recommendation. The latest version of the SOAP specification may be found at L. SOAP defines a protocol for message exchange between applications. The most popular usage is to use SOAP for remote procedure calls (RPC). While one of the constituting aspects of a web service is its reachability via some internet protocol, you might as well define SOAP services accessible via postcards. Despite it's former name, SOAP has nothing more to do with objects than cars have with pets - SOAP messages may, but not necessarily do carry objects, very much like your car may, but does not need to carry your pet. =head2 WSDL WSDL is an acronym for Web Services Description Language. WSDL is a W3C recommendation. The latest version of the WSDL specification may be found at L. WSDL defines a XML-based language for describing web service interfaces, including SOAP interfaces. =head2 WS-I WS-I (Web Services Interoperability Organization) is an open industry organisation chartered to promote Web service interoperability across platforms, operating systems, and programming languages. WS-I publishes profiles, which provide implementation guidelines for how related Web services specifications should be used together for best interoperability. To date, WS-I has finalized the Basic Profile, Attachments Profile and Simple SOAP Binding Profile. SOAP::WSDL aims at complying to the WS-I Basic Profile (but does not implement full support yet). =head2 SOAP message styles =head3 rpc Meant for transporting a RPC message. All contents of the SOAP body are put into a top-level node named equal to the SOAP operation. WS-I Basic Profile allows the use of rpc message style. SOAP::WSDL does not support rpc message style yet. SOAP::Lite supports rpc message style only. =head3 document Meant for transporting arbitrary content. No additional nodes are inserted between the SOAP body and the actual content. WS-I Basic Profile allows the use of document message style. =head2 SOAP encoding styles =head3 encoded =head3 literal =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 391 $ $LastChangedBy: kutterma $ $Id: Glossary.pod 391 2007-11-17 21:56:13Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Manual/Glossary.pod $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/Cookbook.pod010064400017500001750000000217211361134503300177160ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::Cookbook - SOAP::WSDL recipes =head2 Accessing HTTPS webservices You need Crypt::SSLeay installed to access HTTPS webservices. =head2 Accessing protected web services Passing a username and password, or a client certificate and key, to the transport layer is highly dependent on the transport backend. The descriptions below are for HTTP(S) transport using LWP::UserAgent =head3 Accessing HTTP(S) webservices with basic/digest authentication When using SOAP::WSDL::Transport::HTTP (SOAP::Lite not installed), add a method called "get_basic_credentials" to SOAP::WSDL::Transport::HTTP: *SOAP::WSDL::Transport::HTTP::get_basic_credentials = sub { return ($user, $password); }; When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to this backend: *SOAP::Transport::HTTP::Client::get_basic_credentials = sub { return ($user, $password); }; =head3 Accessing HTTP(S) webservices protected by NTLM authentication If you want to connect to a windows server using some Windows Domain Login, please consider using Kerberos instead of the (older) NTLM mechanism - see below. Kerberos and NTLM are (currently) mutually exclusive - when LWP::Authen::Negotiate is installed, it will always be queried (and will always raise an error), even if you don't want to use it. See http://rt.cpan.org/Public/Bug/Display.html?id=32826 for details. You need the L distribution installed to access webservices protected by NTLM authentication. More specifically, you need the Authen::NTLM module from this distribution. Note that this is different from the Authen::NTML distribution by Yee Man Chan also available from CPAN. Your user credentials usually need to include the windows domain or the windows hostname like this: testdomain\testuser or \\testhost\testuser Besides passing user credentials as when accessing a web service protected by basic or digest authentication, you also need to enforce connection keep_alive on the transport backens. To do so, pass a I argument to the new() method of the generated class. This unfortunately means that you have to set the endpoint URL, too: my $interface = MyInterfaces::SERVICE_NAME::PORT_NAME->new({ proxy => [ $url, keep_alive => 1 ] }); You may, of course, decide to just hack the generated class. Be advised that subclassing might be a more appropriate solution - re-generating overwrites changes in interface classes. =head3 Accessing HTTP(S) webservices protected by NTLMv2 There are different variants of NTLM, and by default Authen::NTLM uses the v1 variant. NTLM is a connection-based handshake authentication protocol, which requires three or more requests on the same connection: Request POST Response 401 Unauthorized WWW-Authenticate: NTLM Request Authorization: NTLM Response 401 Unauthorized WWW-Authenticate: NTLM Request Authorization: NTLM Response 200 Ok If you try to access a NTLMv2 protected web service and switch on LWP::Debug by saying use LWP::Debug qw(+); you should see at least two lines containing something like Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAwADACAAAABmb28= ... Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAw ... much longer ... ADACAAAABmb28= If you're talking to a Server using NTLMv2 exclusively, you will only the first line in the debug output, and then an error. To explicitly enable NTLMv2, do the following in your client: use Authen::NTLM; ntlmv2(1); This globally enables the use of NTLMv2. Note that this is a global setting: All clients running in the same perl interpreter will be affected. This can cause unexpected issues when running under mod_perl. =head3 Accessing webservices protected by HTTP Kerberos Authentication Use the L plugin from CPAN. You need to set up GSSAPI to perform the Kerberos authentication, though. How to do this is implementation specific (MIT or Heimdahl). See your Kerberos/GSSAPI documentation for details. (Newer) Windows Web Services usually allow one to use both the Negotiate (Kerberos) and NTLM authentication scheme. =head3 Accessing HTTPS webservices protected by certificate authentication You need Crypt::SSLeay installed to access HTTPS webservices. See L on how to configure client certificate authentication. =head1 XML OUTPUT =head2 Outputting namespaces as prefixes Q: I need to interface with a SOAP server which doesn't accept the following format: 12345 Instead, it requires this: 12345 How do I do this using SOAP::WSDL? A: The following steps are necessary to achieve this result: First, you would need to write a new serializer, which is quite easy, as it just creates the envelope and calls ->serialize_qualified() on $header and $body to fill them in. The new serializer has to declare all namespace prefixes used, the rest is just the same as the original XSD serializer. Second, you'd need to overwrite the start_tag method in L to use the appropriate prefixes for the body elements. In contrast to the original method, it would probably look up the appropriate prefix from some data set in the serializer class, so this could be the appropriate place to load SOAP::WSDL::XSD::Typelib::Element and override the method. Something like this should do (without the handling of specialties like empty or nil elements): %PREFIX_OF = { 'http://services.company.com/' => 'ns2' }; *SOAP::WSDL::XSD::Typelib::Element::start_tag = sub { # use prefix instead of xmlns attribute and copy the rest from # SOAP::WSDL::XSD::Typelib::Element::start_tag my $prefix = $PREFIX_OF{ $_[0]->get_xmlns() }; my $name = $_[1]->{ name } || $self->__get_name(); return "<$prefix:$name>"; } =head1 Skipping unknown XML elements - "lax" XML processing SOAP::WSDL's default serializer L is a "strict" XML processor in the sense that it throws an exception on encountering unknown XML elements. L allows switching off the stric XML processing by passing the C 0> option. =head2 Disabling strict XML processing in a Client Pass the following as C: { strict => 0 } Example: The generated SOAP client is assumed to be "MyInterface::Test". use MyInterface::Test; my $soap = MyInterface::Test->new({ deserializer_args => { strict => 0 } }); my $result = $soap->SomeMethod(); =head2 Disabling strict XML processing in a CGI based server You have to set the deserializer in the transport class explicitly to a L object with the C option set to 0. Example: The generated SOAP server is assumed to be "MyServer::Test". use strict; use MyServer::Test; use SOAP::WSDL::Deserializer::XSD; my $soap = MyServer::Test->new({ transport_class => 'SOAP::WSDL::Server::CGI', dispatch_to => 'main', }); $soap->get_transport()->set_deserializer( SOAP::WSDL::Deserializer::XSD->new({ strict => 0 }) ); $soap->handle(); =head2 Disabling strict XML processing in a mod_perl based server Sorry, this is not implemented yet - you'll have to write your own handler class based on L. =head1 Changing the encoding of a SOAP request SOAP::WSDL uses utf-8 per default: utf-8 is the de-facto standard for webservice ommunication. However, you can change the encoding the transport layer announces by calling C on a client object. You probably have to write your own serializer class too, because the default serializer has the utf-8 encoding hardcoded in the envelope. Just look into SOAP::WSDL::Serializer on how to do that. Don't forget to register your serializer at the serializer factory SOAP::WSDL::Factory::Serializer. =head1 LICENSE AND COPYRIGHT Copyright 2008, 2009 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 583 $ $LastChangedBy: kutterma $ $Id: $ $HeadURL: $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/CodeFirst.pod010064400017500001750000000052731361134503300200360ustar00scottscott=pod =head1 NAME CodeFirst - Writing Code-First Web Services with SOAP::WSDL B. =head2 How Data Class definitions could look like =head3 Moose Of course SOAP::WSDL could (and probably should) just use Moose - it provides the full Metaclass Framework needed for generating Schemas from class definitions. However, Moose is way too powerful for building (just) simple Data Transfer Objects which can be expressed in XML. With Moose, a class could look like this: package MyElements::GenerateBarCode; use Moose; has 'xmlns' => is => 'ro', default => 'http://webservicex.net'; has 'xmlname' => is => 'ro', default => 'GenerateBarCode'; has 'BarCodeParam' => is => 'rw', type => 'MyTypes::BarCodeData'; has 'BarCodeText' => is => 'rw', type => 'String'; 1; This is - despite the condensed syntax - a lot of line noise. =head3 Native SOAP::WSDL SOAP::WSDL::XSD::Typelib::ComplexType (should) provide a simple setup method allowing a even shorter description (and offering the additional performance boost SOAP::WSDL has over Moose): package MyElements::GenerateBarCode; use strice; use warnings; use SOAP::WSDL::XSD::Typelib::Element; use SOAP::WSDL::XSD::Typelib::ComplexType; _namespace 'http://webservicex.net'; # might be better in the SOAP server interface _name 'GenerateBarCode'; _elements BarCodeParam => 'MyTypes::BarCodeData', BarCodeText => 'string'; This would result in the following XML Schema (inside a schema with the namespace "http://webservicex.net" - the namespaces could even be declared outside the DTO classes. =head2 Interface definitions Perl does not have the concept of interfaces. However, Moose provides Roles, which can be used for defining interfaces. However, it's not really necessary to define a interface Interface (in the sense of a Java interface) - a interface class is sufficient. Subroutine attributes could be used for providing additional information - attributes in perl are much like annotations in Java A interface could look like this: package MyServer::BarCode; use strict; use warnings; use SOAP::WSDL::Server::CodeFirst; sub generateBarCode :WebMethod(name= return= body=) { my ($self, $body, $header) = @_; my $result = MyElements::GenerateBarcodeResponse->new(); return $result; }; 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/XSD.pod010064400017500001750000000340221361134503300166040ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::XSD - SOAP::WSDL's XML Schema implementation =head1 DESCRIPTION SOAP::WSDL's XML Schema implementation translates XML Schema definitions into perl classes. Every top-level type or element in a XML schema is translated into a perl class (usually in it's own file). Atomic types are either directly included in the class of their parent's node, or as sub-package in their parent class' file. While the implementation is still incomplete, it covers the XML schema definitions used by most object mappers. =head1 USAGE You can use SOAP::WSDL::XSD based classes just like any perl class - you may instantiate it, inherit from it etc. You should be aware, that SOAP::WSDL::XSD based classes are inside-out classes using Class::Std::Fast, though - things you would expect from hash-based classes like using the blessed hash ref as data storage won't work. Moreover, most all SOAP::WSDL::XSD::Typelib based classes override Class::Std::Fast's default constructor for speed - you should not expect BUILD or START methods to work, unless you call them yourself (or define a new constructor). All SOAP::WSDL::XSD based complexType classes allow a hash ref matching their data structure as only parameter to new(). You may mix hash and list refs and objects in the structure passed to new - as long as the structure matches, it will work fine. All SOAP::WSDL::XSD based simpleType (and builtin) classes accept a single hash ref with the only key "value" and the value to be set as value. =head2 Conversions =head3 Array dereference All SOAP::WSDL::XSD based classes overload arrayification - that is being accessed as a list ref - with a method returning [ $self ]. This means that you can safely use the results of get_ELEMENT calls on complexTypes as list refs (you'll have to check for definedness, though - see L for details. To iterate over a (potential) list of child elements just do the following: if (defined $obj->get_ELEMENT()) { for (@{ $obj->get_ELEMENT() }) { ... } } This is especially useful in mini-languages like L, where you could say <%IF_DEFINED obj.get_ELEMENT %> <%LOOP obj.get_ELEMENT %> ... <%/LOOP> <%IF%> Note that this does not work in HTML::Template::Compiled yet - the code generated for the template checks UNIVERSAL::isa instead of dereferencing. There's a ticket open in HTC to solve the issue. =head3 as_hash_ref SOAP::WSDL::XSD::Typelib::ComplexType based objects have a method as_hash_ref, which returns the object's content as a hash reference. This can be convenient for cloning: my $class = ref $old; my $clone = $class->new( $old->as_hash_ref() ); To convert from one type to another, you can just say my $new = MyTypes::NewType->new( $old->as_hash_ref() ); Of course this will only work if MyTypes::NewType has a superset of the old object class' elements. Note that XML attribute data is not included in the hash ref output yet. =head1 HOW IT WORKS =head2 Base classes SOAP::WSDL::XSD provides a set of base classes for the construction of XML schema defined type classes. =head3 Builtin types SOAP::WSDL::XSD provides classes for all builtin XML Schema datatypes. For a list and reference on these classes, see SOAP::WSDL::XSD::Typelib::Builtin. =head3 Derivation classes For derivation by list, the list derivation class SOAP::WSDL::XSD::Typelib::Builtin::list exists. Derivation by restriction is handled without the help of additional classes. =head3 Element construction class For the construction of element classes, the element superclass SOAP::WSDL::XSD::Typelib::Element exists. All elements are ultimately derived from this class. Elements may inherit from type classes, too - see L for details. =head3 complexType construction class For the construction of complexType classes, the construction class SOAP::WSDL::XSD::Typelib::ComplexType is provided. It provides a __factory method for placing attributes in generated classes, and generating appropriate setter/getter accessors. The setters are special: They handle complex data structures of any type (meaning hash refs, list refs and objects, and any combination of them), as long as their structure matches the expected structure. =head1 TRANSLATION RULES =head2 element TODO add more elaborate description =head3 element with type attribute Elements defined by referencing a builtin or user defined type inherit from SOAP::WSDL::XSD::Typelib::Element and from the corresponding type class. Element Type base class class ^ ^ | | ------------ | Element type="" class =head3 element with ref attribute Elements defined by referencing another element inherit from the corresponding element class. referenced Element class ^ | Element ref="" class =head3 element with atomic simpleType Elements defined by a atomic simpleType from SOAP::WSDL::XSD::Typelib::Element and from the base type of the atomic type. Element atomic Type base class base class ^ ^ | | -------------- | element simpleType class =head3 element with atomic complexType Elements defined with a atomic complexType inherit from SOAP::WSDL::XSD::Typelib::Element and from SOAP::WSDL::XSD::Typelib::ComplexType. Element complexType base class base class ^ ^ | | -------------- | element complexType class =head2 complexType TODO add more elaborate description Some content models are not implemented yet. The content models implemented are described below. =head3 complexType with "all" variety Complex types with "all" variety inherit from SOAP::WSDL::XSD::Typelib::ComplexType, and call it's factory method for creating fields and accessors/mutators for the complexType's elements. All element's type classes are loaded. Complex type classes have a "has a" relationship to their element fields. Element fields may either be element classes (for element ref="") or type classes (for element type=""). No extra element classes are created for a complexType's elements. complexType base class ^ | complexType all ---------------- has a element name="a" ------------> Element or type class object element name="b" ------------> Element or type class object The implementation for all does enforce the order of elements as described in the WSDL, even though this is not required by the XML Schema specification. =head3 complexType with "sequence" variety The implementation of the "sequence" variety is the same as for all. =head3 complexType with "choice" variety The implementation for choice currently is the same as for all - which means, no check for occurrence are made. =head3 complexType with complexContent content model Note that complexType classes with complexContent content model don't exhibit their type via the xsi:type attribute yet, so they currently cannot be used as a replacement for their base type. SOAP::WSDL's XSD deserializer backend does not recognize the xsi:type="" attribute either yet. =over =item * restriction variety ComplexType classes with restriction variety inherit from their base type. No additional processing or content checking is performed yet. complexType base type class ^ | complexType restriction =item * extension variety ComplexType classes with extension variety inherit from the XSD base complexType class and from their base type. Extension classes are checked for (re-)defining all elements of their parent class. Note that a derived type's elements (=properties) overrides the getter / setter methods for all inherited elements. All object data is stored in the derived type's class, not in the defining class (See L for a discussion on inside out object data storage). No additional processing or content checking is performed yet. complexType complexType base class base type class ^ ^ | | ----------------- | complexType extension =back =head2 SimpleType TODO add more elaborate description Some derivation methods are not implemented yet. The derivation methods implemented are described below. =head3 Derivation by list Derivation by list is implemented by inheriting from both the base type and SOAP::WSDL::XSD::Typelib::XSD::list. =head3 Derivation by restriction Derivation by restriction is implemented by inheriting from a base type and applying the required restrictions. =head1 FACETS XML Schema facets are not implemented yet. They will probably implemented some day by putting constant methods into the correspondent classes. =head2 Attributes The attribute set for a XML element (derived from anySimpleType or complexType) is implemented as a sub-package of the element derived from SOAP::WSDL::XSD::Typelib::AttributeSet. The sub-package is named as the corresponding type or element package, suffixed with C. The suffix "XmlAttr" has carefully been chosen to avoid potential naming clashes: The name XmlAttr cannot be included as element or type name in XML schemas - the XML standard bans the use of names starting with "xml" (case-insensitive). All XML attributes for a XML element are set- and retrievable via the method C. The name is chosen to allow mimicking SOAP::Lite's behaviour, which allows setting a SOAP::Data object's attributes via C. my $attrSet = $obj->attr(); $obj->attr({ whitespace => 'preserve', nillable => 1, }); SOAP::WSDL::XSD::Typelib::AttributeSet is derived from SOAP::WSDL::XSD::Typelib::ComplexType with content model C. The individual attributes can be set and retrieved via the respective set_FOO / get_FOO methods. The C method provides auto-vivification: An xml object's attribute set is instantiated when accessed. Auto-vivification is only triggered if there actually B a set of attributes for the class/object in question, so you may want to test whether the result of ->attr is defined: my $attr = $unknownObject->attr(); if (defined($attr)) { $unknownObject->attr({ some => 'value', }); } =head2 group CAVEAT: Group resolution is not implemented yet. XML Schema Group definitions are just treated as aliases that can be inserted in complexType definitions by referencing them. That is, there's no difference between a complexType with simpleContent and a sequence of three elements, and a complexType with simpleContent referencing a group containing the same sequence of elements. =head1 CAVEATS =over =item * START and BUILD are not being called In contrast to "normal" Class::Std::Fast based objects, the classes of the SOAP::WSDL::XSD::Typelib:: hierarchy (and all type and element classes generated by SOAP::WSDL) override Class::Std's constructor for performance reasons. If you inherit from such a class and place a START or BUILD method in it, it will not get called - at least not unless you place something like this at the top of you code: use Class::Std::Fast::Storable; In this case, Class::Std::Fast::Storable will export a new() method into your class, which in turn calls START and BUILD. The constructors of all SOAP::WSDL::XSD::Typelib:: classes don't ! =back =head1 BUGS AND LIMITATIONS The following XML Schema declaration elements are not supported yet: =head2 XML Schema elements partially supported =head3 Type definition elements =over =item * simpleContent simpleContent is only supported with a restriction or extension with a C attribute. simpleContent declarations deriving from a atomic type are not supported (yet). =back =head3 Inclusion elements =over =item * import The import inclusion element requires the schemaLocation attribute for resolving the XML schema to import. Support for the import element is implemented in L, so alternative parsers may or may not support the import element. L keeps track of included schemas and prevents import loops. =back =head3 Facets The following XML Schema declaration elements are supported, but have no effect yet. =over =item * enumeration =item * fractionDigits =item * length =item * maxExclusive =item * maxInclusiove =item * maxLength =item * minExclusive =item * minInclusive =item * minLength =item * pattern =item * totalDigits =item * whitespace =back =head2 XML Schema elements not implemented =head3 Declaration elements =over =item * notation =back =head3 Content model definition elements =over =item * any The horror of each XML schema implementation: Just anything... C declarations are not supported yet. =item * anyAttribute =item * attributeGroup C declarations actually just are macros for XML Schema writers: Including an attributeGroup in a declaration has the same effect as including all attributes in the group. Just not implemented yet. =item * group The group definition element is not supported yet. =back =head3 Identity definition elements These declaration elements don't declare XML elements, but apply identity constraints. They have no effect yet. =over =item * field =item * key =item * keyref =item * selector =item * unique =back =head3 Inclusion elements =over =item * include Use of the include inclusion element is forbidden by the WS-I basic profile. It is not supported (yet). =item * redefine Not supported (yet). =back =head3 * Documentation elements =over =item * appinfo The appinfo documentation element is ignored. =back =head1 LICENSE Copyright 2007,2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 390 $ $LastChangedBy: kutterma $ $Id: Client.pm 390 2007-11-16 22:18:32Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/Deserializer.pod010064400017500001750000000021071361134420300205650ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::Deserializer - Deserializer classes =head1 DESERIALIZER CLASSES Deserializer classes convert SOAP messages to perl data structures. SOAP::WSDL comes with several builtin serializer classes: =over =item * L Creates SOAP::WSDL::XSD objects from SOAP messages. Default deserializer for generated interfaces and SOAP::WSDL::Client. =item * L Creates perl hash structures from SOAP messages. =item * L Creates SOAP::SOM objects from SOAP messages. Default deserializer for SOAP::WSDL. See L for more information on SOAP::SOM objects. =back =head1 WRITING YOUR OWN DESERIALIZER See L. =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/Parser.pod010064400017500001750000000160071361134503300174050ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::Parser - How SOAP::WSDL parses XML messages =head1 Which XML message does SOAP::WSDL parse ? Naturally, there are two kinds of XML documents (or messages) SOAP::WSDL has to parse: =over =item * WSDL definitions =item * SOAP messages =back There are different parser implementations available for SOAP messages and WSDL definitions. =head1 WSDL definitions parser =head2 SOAP::WSDL::Expat::WSDLParser A parser for WSDL definitions based on L. my $parser = SOAP::WSDL::Expat::WSDLParser->new(); my $wsdl = $parser->parse_file( $filename ); The WSDL parser creates a tree of perl objects, whose root is a L element. =head1 SOAP messages parser =head2 SOAP::WSDL::Expat::MessageParser L converts SOAP messages to SOAP::WSDL::XSD object trees. It uses a class resolvers for finding out which class a particular XML element should be of, and type libs containing these classes. =head3 Creating a class resolver The easiest way for creating a class resolver is to run SOAP::WSDL's generator. See L. The class resolver must implement a class method "get_class", which is passed a list ref of the current element's XPath (relative to Body), split by /. This method must return a class name appropriate for a XML element. A class resolver package might look like this: package ClassResolver; my %class_list = ( 'EnqueueMessage' => 'Typelib::TEnqueueMessage', 'EnqueueMessage/MMessage' => 'Typelib::TMessage', 'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI', 'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string', ); sub new { return bless {}, 'ClassResolver' }; sub get_class { my $name = join('/', @{ $_[1] }); return ($class_list{ $name }) ? $class_list{ $name } : warn "no class found for $name"; }; 1; =head3 Skipping unwanted items Sometimes there's unnecessary information transported in SOAP messages. To skip XML nodes (including all child nodes), just edit the type map for the message and set the type map entry to '__SKIP__'. In the example above, EnqueueMessage/StuffIDontNeed and all child elements are skipped. my %class_list = ( 'EnqueueMessage' => 'Typelib::TEnqueueMessage', 'EnqueueMessage/MMessage' => 'Typelib::TMessage', 'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI', 'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string', 'EnqueueMessage/StuffIDontNeed' => '__SKIP__', 'EnqueueMessage/StuffIDontNeed/Foo' => 'SOAP::WSDL::XSD::Builtin::string', 'EnqueueMessage/StuffIDontNeed/Bar' => 'SOAP::WSDL::XSD::Builtin::string', ); Note that only SOAP::WSDL::Expat::MessageParser implements skipping elements at the time of writing. =head3 Creating type lib classes Every element must have a correspondent one in the type library. Builtin types should be resolved as SOAP::WSDL::XSD::Builtin::* classes Creating a type lib is easy: Just run SOAP::WSDL's generator - it will create both a typemap and the type lib classes for a WSDL file. Sometimes it is nessecary to create type lib classes by hand - not all WSDL definitions are complete. For writing your own lib classes, see L, L and L. =head2 SOAP::WSDL::Expat::Message2Hash Transforms a SOAP message into a perl hash refs. Using this parser is usually triggered by calling the C method of SOAP::WSDL, or by using L. Acts somewhat like XML::Simple, but faster. The following restrictions apply: =over =item * Ignores all namespaces =item * Ignores all attributes =item * Does not handle mixed content =item * The SOAP header is ignored =back =cut =head1 OLD SAX HANDLER Historically, SOAP::WSDL used SAX for parsing XML. The SAX handlers were implemented as L handlers, which also worked with L. Support for SAX and L in SOAP::WSDL is discontinued for the following reasons: =over =item * Speed L is faster than L - at least when optimized for speed. High parsing speed is one of the key requirements for a SOAP toolkit - if XML serializing and (more important) deserializing are not fast enough, the whole toolkit is unusable. =item * Availability L is more popular than L. =item * Stability XML::LibXML is based on the libxml2 library. Several versions of libxml2 are known to have specific bugs. As a workaround, there are often several versions of libxml2 installed on one system. This may lead to problems on operating systems which cannot load more than one version of a shared library simultaneously. XML::LibXML is also still under development, while XML::Parser has had time to stabilize. =item * SOAP::Lite uses XML::Parser L uses L if available. SOAP::WSDL should not require users to install both L and L. =back The old SAX handler historically used in SOAP::WSDL are not included in the SOAP::WSDL package any more. However, they may be obtained from the "attic" directory in SOAP::WSDL's SVN repository at https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/attic =over =item * SOAP::WSDL::SAX::WSDLHandler This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL works with. It's built as a native handler for XML::LibXML, but will also work with XML::SAX::ParserFactory. To parse a WSDL file, use one of the following variants: my $parser = XML::LibXML->new(); my $handler = SOAP::WSDL::SAX::WSDLHandler->new(); $parser->set_handler( $handler ); $parser->parse( $xml ); my $data = $handler->get_data(); my $handler = SOAP::WSDL::SAX::WSDLHandler->new({ base => 'XML::SAX::Base' }); my $parser = XML::SAX::ParserFactor->parser( Handler => $handler ); $parser->parse( $xml ); my $data = $handler->get_data(); =item * SOAP::WSDL::SAX::MessageHandler This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL works with. It's built as a native handler for XML::LibXML, but will also work with XML::SAX::ParserFactory. Can be used for parsing both streams (chunks) and documents. =back =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself. =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 391 $ $LastChangedBy: kutterma $ $Id: Parser.pod 391 2007-11-17 21:56:13Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Manual/Parser.pod $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual/WS_I.pod010064400017500001750000001104311361134503300167460ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual::WS_I - How SOAP::WSDL complies to WS-I Basic Profile 1.0 =head1 DESCRIPTION This document gives an overview about how SOAP::WSDL confirms to the rules of the WS-I Basic Profile 1.0 found at L Errata are not yet worked in. You may find rules mis-categorized, especially in the "not applicable" section. Such mis-categorizations are documentation bugs, please feel free to report them. Rules are categorized into the following sections: =over =item * RULES CONFIRMED This section contains rules SOAP::WSDL follows. Conformance to these rules may be assured by a test. =item * RULES NOT CONFIRMED This section contains rules SOAP::WSDL does not follow yet. These may be considered as bugs. =item * RULES NOT APPLICABLE WS-I Basic Profile contains rules for web services as a whole. SOAP::WSDL only plays the part of one layer in a Web Service CONSUMER / RECEIVER, thus does not implement some parts the WS-I Basic Profile references. This section contains rules not applicable for SOAP::WSDL, because they refer to parts SOAP::WSDL does not implement. =back =head1 RULES CONFIRMED =head2 R1005 A MESSAGE MUST NOT contain soap:encodingStyle attributes on any of the elements whose namespace name is "http://schemas.xmlsoap.org/soap/envelope/". SOAP::WSDL::Serializer::SOAP11 does not add soap:encodingStyle attributes on any element. =head2 R1006 A MESSAGE MUST NOT contain soap:encodingStyle attributes on any element that is a child of soap:Body. SOAP::WSDL::Serializer::SOAP11 does not add soap:encodingStyle attributes on any element. =head2 R1008 A MESSAGE MUST NOT contain a Document Type Declaration. SOAP::WSDL::Serializer::SOAP11 does not add DTDs. =head2 R1009 A MESSAGE MUST NOT contain Processing Instructions. SOAP::WSDL::Serializer::SOAP11 does not add Processing Instructions =head2 R1010 A RECEIVER MUST accept messages that contain an XML Declaration. SOAP::WSDL::Expat::MessageParser allows the use of XML Declarations. =head2 R1011 A MESSAGE MUST NOT have any element children of soap:Envelope following the soap:Body element. SOAP::WSDL::Serializer::SOAP11 does not emit children of soap:Envelope following the soap:Body element. Other serializers may behave different. =head2 R1012 A MESSAGE MUST be serialized as either UTF-8 or UTF-16. SOAP::WSDL::Serializer::SOAP11 serializes messages as UTF-8. =head2 R1018 The media type of a MESSAGE's envelope MUST indicate the correct character encoding, using the charset parameter. SOAP::WSDL::Transport::HTTP sets the Content-type header to "text/xml; charset=utf8". SOAP::Transport does, too. Other transport backends may behave different. =head2 R1014 The children of the soap:Body element in a MESSAGE MUST be namespace qualified. SOAP::WSDL::Serializer::SOAP11 emits namespace-qualified child elements of the soap:Body element. =head2 R1017 A RECEIVER MUST NOT mandate the use of the xsi:type attribute in messages except as required in order to indicate a derived type (see XML Schema Part 1: Structures, Section 2.6.1). SOAP::WSDL::Expat::MessageParser does not require the use of xsi:type attributes, but uses typemaps instead. Other deserializers may not comply to this rule. =head2 R1028 When a Fault is generated by a RECEIVER, further processing SHOULD NOT be performed on the SOAP message aside from that which is necessary to rollback, or compensate for, any effects of processing the message prior to the generation of the Fault. A fault is generated when an error occurs processing the message. SOAP::WSDL::Deserializer::SOAP11 does not perform any additional processing after an error occurred. =head2 R1029 Where the normal outcome of processing a SOAP message would have resulted in the transmission of a SOAP response, but rather a SOAP Fault is generated instead, a RECEIVER MUST transmit a SOAP Fault message in place of the response. A fault is generated when an error occurs processing the message. =head2 R1030 A RECEIVER that generates a SOAP Fault SHOULD notify the end user that a SOAP Fault has been generated when practical, by whatever means is deemed appropriate to the circumstance. Via return value. =head2 R1140 A MESSAGE SHOULD be sent using HTTP/1.1. SOAP::WSDL::Transport::HTTP uses HTTP/1.1 =head2 R1141 A MESSAGE MUST be sent using either HTTP/1.1 or HTTP/1.0. SOAP::WSDL::Transport::HTTP uses HTTP/1.1 =head2 R1107 A RECEIVER MUST interpret SOAP messages containing only a soap:Fault element as a Fault. SOAP::WSDL::Deserializer::SOAP11 does this. =head2 R1132 A HTTP request MESSAGE MUST use the HTTP POST method. Both SOAP::WSDL::Transport::HTTP and SOAP::Transport::HTTP use POST. =head2 R1108 A MESSAGE MUST NOT use the HTTP Extension Framework (RFC2774). SOAP::WSDL::Transport::HTTP does not use the HTTP Extension framework, however SOAP::Transport::HTTP use M-POST if POST was not successful. To be sure you comply to this rule, use SOAP::WSDL::Transport::HTTP as transport backend. =head2 R1109 The value of the SOAPAction HTTP header field in a HTTP request MESSAGE MUST be a quoted string. SOAP::WSDL::Client always quotes the SOAPAction header. =head2 R1119 A RECEIVER MAY respond with a Fault if the value of the SOAPAction HTTP header field is not quoted. SOAP::WSDL does not apply any processing on the SOAPAction header field. =head2 R1131 A CONSUMER MAY automatically redirect a request when it encounters a "307 Temporary Redirect" HTTP status code in a response. LWP::UserAgent (used by SOAP::WSDL::Transport::HTTP and SOAP::Transport::HTTP) accepts up to 7 levels of redirect by default. =head2 R2113 A MESSAGE containing serialized arrays MUST NOT include the soapenc:arrayType attribute. SOAP::WSDL does not natively support soapenc::arrayType. =head2 R2114 The target namespace for WSDL definitions and the target namespace for schema definitions in a DESCRIPTION MAY be the same. SOAP::WSDL does not impose any constraints on the target namespace for WSDL definitions or schema definitions. =head2 R2301 The order of the elements in the soap:body of a MESSAGE MUST be the same as that of the wsdl:parts in the wsdl:message that describes it. SOAP::WSDL obeys the part order. =head2 R2712 A document-literal binding MUST be represented on the wire as a MESSAGE with a soap:Body whose child element is an instance of the global element declaration referenced by the corresponding wsdl:message part. If defined accordingly in the DESCRIPTION, SOAP::WSDL issues document-literal binding operation MESSAGES conforming to this rule. =head2 R2748 A CONSUMER MUST NOT interpret the presence of the wsdl:required attribute on a soapbind extension element with a value of "false" to mean the extension element is optional in the messages generated from the WSDL description. SOAP::WSDL does not imterpret the wsdl:required attribute at all. =head2 R5000 An INSTANCE MAY require the use of HTTPS. SOAP::WSDL supports https. =head2 R5010 An INSTANCE MAY require the use of HTTPS with mutual authentication. SOAP::WSDL supports all kinds of authentication known to LWP::UserAgent =head2 R2742 A MESSAGE MAY contain a fault detail entry in a SOAP fault that is not described by a wsdl:fault element in the corresponding WSDL description. SOAP::WSDL does not emit such faults. Such faults can be processed by adding custom maps to the type maps for SOAP::WSDL::Expat::MessageParser. =head2 R2744 A HTTP request MESSAGE MUST contain a SOAPAction HTTP header field with a quoted value equal to the value of the soapAction attribute of soapbind:operation, if present in the corresponding WSDL description. SOAP::WSDL uses the soapAction attribute from soapbind:operation as SOAPAction header in generated code. Alternative WSDL parsers / code generator have to assure they pass the correct soap_action to SOAP::WSDL::Client. The interpreting SOAP::WSDL client does not conform to this rule, but "guesses" the SOAPAction header from the operation name and the top node's namespace. =head2 R2745 A HTTP request MESSAGE MUST contain a SOAPAction HTTP header field with a quoted empty string value, if in the corresponding WSDL description, the soapAction of soapbind:operation is either not present, or present with an empty string as its value. SOAP::WSDL::Client always assures the SOAPaction header is quoted, thus automatically inserts the empty string if no SOAPAction header is defined. =head2 R1015 A RECEIVER MUST generate a fault if they encounter a message whose document element has a local name of "Envelope" but a namespace name that is not "http://schemas.xmlsoap.org/soap/envelope/". SOAP::WSDL::Expat::MessageParser checks the namespace of the SOAP envelope. SOAP::WSDL::Expat::MessageParser does not check that Envelope is the root element, yet. =head2 R1110 An INSTANCE MAY accept connections on TCP port 80 (HTTP) SOAP::WSDL::Server::CGI may be used in a web server listening at port 80. =head2 R1124 An INSTANCE MUST use a 2xx HTTP status code for responses that indicate a successful outcome of a request. SOAP::WSDL::Server::CGI sends a 2xx HTTP status code for successful requests. =head2 R1111 An INSTANCE SHOULD use a "200 OK" HTTP status code for responses that contain a SOAP message that is not a SOAP fault. SOAP::WSDL::Server::CGI does this. =head2 R1112 An INSTANCE SHOULD use either a "200 OK" or "202 Accepted" HTTP status code for a response that does do not contain a SOAP message but indicates successful HTTP outcome of a request. SOAP::WSDL::Server::CGI does this. =head2 R1130 An INSTANCE MUST use HTTP status code "307 Temporary Redirect" when redirecting a request to a different endpoint. SOAP::WSDL::Server::CGI has no means of redirecting. The web server running a SOAP::WSDL::Server::CGI script is responsible for redirecting with a 307 HTTP status code. =head2 R1125 An INSTANCE MUST use a 4xx HTTP status code for responses that indicate a problem with the format of the request. SOAP::WSDL does this. =head2 R1113 An INSTANCE SHOULD use a "400 Bad Request "HTTP status code, if the request message is a malformed HTTP request, or not well-formed XML. SOAP::WSDL does this. =head2 R1114 An INSTANCE SHOULD use a "405 Method not Allowed" HTTP status code if the request method was not "POST". SOAP::WSDL does this. =head2 R1115 An INSTANCE SHOULD use a "415 Unsupported Media Type" HTTP status code if the Content-Type HTTP request header did not have a value consistent with the value specified for the corresponding binding of the input message. SOAP::WSDL::Server::CGI does not support any content type other than text/xml and application/xml yet. =head1 RULES NOT CONFIRMED =head2 R4001 A RECEIVER MUST accept messages that include the Unicode Byte Order Mark (BOM). May automatically work with XML::Parser::Expat, but is not tested yet. TODO write test. If not confirmed, add encoding support. =head2 R1002 A RECEIVER MUST accept fault messages that have any number of elements, including zero, appearing as children of the detail element. Such children can be qualified or unqualified. Partially confirmed: This only works when the fault detail elements are added to the deserializer's typemap. TODO add processing of arbitrary content of faults to SOAP::WSDL::Expat::MessageParser =head2 R1003 A RECEIVER MUST accept fault messages that have any number of qualified or unqualified attributes, including zero, appearing on the detail element. The namespace of qualified attributes can be anything other than "http://schemas.xmlsoap.org/soap/envelope/". TODO add processing of arbitrary attributes to SOAP::WSDL::SOAP::Typelib::Fault11 =head2 R1016 A RECEIVER MUST accept fault messages that carry an xml:lang attribute on the faultstring element. SOAP::WSDL::Expat::MessageParser currently ignores all attributes. TODO add processing of the xml:lang attribute to SOAP::WSDL::SOAP::Typelib::Fault11 =head2 R1007 A MESSAGE described in an rpc-literal binding MUST NOT contain soap:encodingStyle attribute on any elements are grandchildren of soap:Body. SOAP::WSDL::Serializer::SOAP11 does not add soap:encodingStyle attributes on any element. However, rpc-literal bindings are not supported, yet. TODO support rpc-literal bindings. =head2 R2008 In a DESCRIPTION the value of the location attribute of a wsdl:import element SHOULD be treated as a hint. The wsdl:import element imports the referenced WSDL definition. This is rather hard-wired and does not allow one to specify a wsdl:import without a resolvable location in SOAP::WSDL. =head2 R4002 A DESCRIPTION MAY include the Unicode Byte Order Mark (BOM). TODO Test. =head2 R4003 A DESCRIPTION MUST use either UTF-8 or UTF-16 encoding. TODO Test whether UTF-16 works. =head2 R2020 The wsdl:documentation element MAY occur as a child of the wsdl:import element in a DESCRIPTION. Not tested yet. =head2 R2024 The wsdl:documentation element MAY occur as a first child of the wsdl:definitions element in a DESCRIPTION. TODO Test. =head2 R2027 If during the processing of an element in the WSDL namespace in a description, a consumer encounters a WSDL extension element amongst its element children, that has a wsdl:required attribute with a boolean value of "true" that the consumer does not understand or cannot process, the CONSUMER MUST fail processing of that element in the WSDL namespace. TODO Implement support for wsdl:required =head2 R2750 A CONSUMER MUST ignore a SOAP response carried in a response from a one-way operation. SOAP::WSDL does not ignore the SOAP response from a one way operation yet. TODO Define operation type signature, and ignore result from one way operations. =head2 R2747 A CONSUMER MUST understand and process all WSDL 1.1 SOAP Binding extension elements, irrespective of the presence or absence of the wsdl:required attribute on an extension element; and irrespective of the value of the wsdl:required attribute, when present. SOAP::WSDL does not implement all WSDL 1.1 SOAP Binding extension yet. TODO check and implement. =head2 R2800 A DESCRIPTION MAY use any construct from XML Schema 1.0. SOAP::WSDL's WSDL parser doen not allow all constructs from XML Schema 1.0 to be used. TODO become "minimal conformant". =head1 RULES NOT APPLICABLE =head2 R0004 A MESSAGE MAY contain conformance claims, as specified in the conformance claim schema. SOAP::WSDL::Serializer::SOAP11 does not add conformance claims. Other serializers may act different. =head2 R0005 A MESSAGE's conformance claims MUST be carried as SOAP header blocks. SOAP::WSDL::Serializer::SOAP11 does not add conformance claims. Other serializers may act different. =head2 R0006 A MESSAGE MAY contain conformance claims for more than one profile. SOAP::WSDL::Serializer::SOAP11 does not add conformance claims. Other serializers may act different. =head2 R0007 A SENDER MUST NOT use the soap:mustUnderstand attribute when sending a SOAP header block containing a conformance claim. SOAP::WSDL::Serializer::SOAP11 does not add conformance claims. Other serializers may act different. =head2 R3020 REGDATA of type uddi:tModel claiming conformance with a Profile MUST be categorized using the ws-i-org:conformsTo:2002_12 taxonomy. SOAP::WSDL does not publish web services yet. =head2 R3030 REGDATA of type uddi:tModel claiming conformance with a Profile MUST use the ws-i-org:conformsTo:2002_12 categorization value corresponding to the conformance claim URI for that Profile. SOAP::WSDL does not publish web services yet. =head2 R3021 A REGISTRY MUST support the WS-I Conformance category system by adding the ws-i-org:conformsTo:2002_12 tModel definition to its registry content. SOAP::WSDL does not publish web services yet. =head2 R3005 REGDATA other than uddi:tModel elements representing conformant Web service types MUST NOT be categorized using the ws-i-org:conformsTo:2002_12 taxonomy and a categorization of "http://ws-i.org/profiles/basic/1.0". SOAP::WSDL does not publish web services yet. =head2 R3004 REGDATA of type uddi:tModel MUST be constructed so that the conformance claim it makes is consistent with the conformance claim made by the wsdl:binding to which it refers. SOAP::WSDL does not publish web services yet. =head2 R1000 When a MESSAGE contains a soap:Fault element, that element MUST NOT have element children other than faultcode, faultstring, faultactor and detail. SOAP::WSDL does not send fault messages. However, SOAP::WSDL::SOAP::Typelib::Fault11 complies to this rule. =head2 R1001 When a MESSAGE contains a soap:Fault element its element children MUST be unqualified. SOAP::WSDL does not send fault messages. However, SOAP::WSDL::SOAP::Typelib::Fault11 complies to this rule. =head2 R1004 When a MESSAGE contains a faultcode element the content of that element SHOULD be one of the fault codes defined in SOAP 1.1 or a namespace qualified fault code. SOAP::WSDL does not send fault messages. However, the fault issued by SOAP::WSDL::Deserializer comply to this rule. =head2 R1031 When a MESSAGE contains a faultcode element the content of that element SHOULD NOT use of the SOAP 1.1 "dot" notation to refine the meaning of the Fault. SOAP::WSDL does not send fault messages. However, the fault issued by SOAP::WSDL::Deserializer comply to this rule. =head2 R1013 A MESSAGE containing a soap:mustUnderstand attribute MUST only use the lexical forms "0" and "1". SOAP::WSDL does not add soap:mustUnderstand attributes. =head2 R1025 A RECEIVER MUST handle messages in such a way that it appears that all checking of mandatory header blocks is performed before any actual processing. SOAP::WSDL does not check mandatory header blocks yet. =head2 R1027 A RECEIVER MUST generate a "soap:MustUnderstand" fault when a message contains a mandatory header block (i.e., one that has a soap:mustUnderstand attribute with the value "1") targeted at the receiver (via soap:actor) that the receiver does not understand. SOAP::WSDL does not check mandatory header blocks yet. =head2 R1120 An INSTANCE MAY use the HTTP state mechanism ("Cookies"). SOAP::WSDL::Server::CGI does not use cookies. A web server running a SOAP::WSDL::Server::CGI script may use cookies.. =head2 R1122 An INSTANCE using Cookies SHOULD conform to RFC2965. SOAP::WSDL::Server::CGI does not use cookies. A web server running a SOAP::WSDL::Server::CGI script may use cookies.. =head2 R1121 An INSTANCE SHOULD NOT require consumer support for Cookies in order to function correctly SOAP::WSDL::Server::CGI does not use cookies. A web server running a SOAP::WSDL::Server::CGI script may use cookies. =head2 R1123 The value of the cookie MUST be considered to be opaque by the CONSUMER. SOAP::WSDL::Server::CGI does not use cookies. A web server running a SOAP::WSDL::Server::CGI script may use cookies. =head2 R2028 A DESCRIPTION using the WSDL namespace (prefixed "wsdl" in this Profile) MUST be valid according to the XML Schema found at "http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd". See 2029. =head2 R2029 A DESCRIPTION using the WSDL SOAP binding namespace (prefixed "soapbind" in this Profile) MUST be valid according to the XML Schema found at "http://schemas.xmlsoap.org/wsdl/soap/2003-02-11.xsd". Although the Profile requires WSDL descriptions to be Schema valid, it does not require consumers to validate WSDL documents. It is the responsibility of a WSDL document's author to assure that it is Schema valid. =head2 R2001 A DESCRIPTION MUST only use the WSDL "import" statement to import another WSDL description. SOAP::WSDL (partially) supports the wsdl:import statement. The wsdl:include statement is not supported. It's the responsibility of the WSDL author to use only the wsdl:import statement for importing WSDL descriptions. =head2 R2002 To import XML Schema Definitions, a DESCRIPTION MUST use the XML Schema "import" statement. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2003 A DESCRIPTION MUST use the XML Schema "import" statement only within the xsd:schema element of the types section. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2004 A DESCRIPTION MUST NOT use the XML Schema "import" statement to import a Schema from any document whose root element is not "schema" from the namespace "http://www.w3.org/2001/XMLSchema". SOAP::WSDL has no means of generating WSDL definitions. =head2 R2009 An XML Schema directly or indirectly imported by a DESCRIPTION MAY include the Unicode Byte Order Mark (BOM). SOAP::WSDL has no means of generating WSDL definitions. =head2 R2010 An XML Schema directly or indirectly imported by a DESCRIPTION MUST use either UTF-8 or UTF-16 encoding. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2011 An XML Schema directly or indirectly imported by a DESCRIPTION MUST use version 1.0 of the eXtensible Markup Language W3C Recommendation. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2007 A DESCRIPTION MUST specify a non-empty location attribute on the wsdl:import element. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2022 When they appear in a DESCRIPTION, wsdl:import elements MUST precede all other elements from the WSDL namespace except wsdl:documentation. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2023 When they appear in a DESCRIPTION, wsdl:types elements MUST precede all other elements from the WSDL namespace except wsdl:documentation and wsdl:import. SOAP::WSDL has no means of generating WSDL definitions. =head2 R4004 A DESCRIPTION MUST use version 1.0 of the eXtensible Markup Language W3C Recommendation. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2005 The targetNamespace attribute on the wsdl:definitions element of a description that is being imported MUST have same the value as the namespace attribute on the wsdl:import element in the importing DESCRIPTION. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2021 The wsdl:documentation element MAY occur as a child of the wsdl:part element in a DESCRIPTION. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2025 A DESCRIPTION containing WSDL extensions MUST NOT use them to contradict other requirements of the Profile. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2026 A DESCRIPTION SHOULD NOT include extension elements with a wsdl:required attribute value of "true" on any WSDL construct (wsdl:binding, wsdl:portType, wsdl:message, wsdl:types or wsdl:import) that claims conformance to the Profile. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2101 A DESCRIPTION MUST NOT use QName references to elements in namespaces that have been neither imported, nor defined in the referring WSDL document. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2102 A QName reference to a Schema component in a DESCRIPTION MUST use the namespace defined in the targetNamespace attribute on the xsd:schema element, or to a namespace defined in the namespace attribute on an xsd:import element within the xsd:schema element. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2105 All xsd:schema elements contained in a wsdl:types element of a DESCRIPTION MUST have a targetNamespace attribute with a valid and non-null value, UNLESS the xsd:schema element has xsd:import and/or xsd:annotation as its only child element(s). SOAP::WSDL has no means of generating WSDL definitions. =head2 R2110 In a DESCRIPTION, array declarations MUST NOT extend or restrict the soapenc:Array type. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2111 In a DESCRIPTION, array declarations MUST NOT use wsdl:arrayType attribute in the type declaration. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2112 In a DESCRIPTION, array declaration wrapper elements SHOULD NOT be named using the convention ArrayOfXXX. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2201 A document-literal binding in a DESCRIPTION MUST, in each of its soapbind:body element(s), have at most one part listed in the parts attribute, if the parts attribute is specified. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2210 If a document-literal binding in a DESCRIPTION does not specify the parts attribute on a soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one wsdl:parts. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2202 A wsdl:binding in a DESCRIPTION MAY contain soapbind:body element(s) that specify that zero parts form the soap:Body. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2203 An rpc-literal binding in a DESCRIPTION MUST refer, in its soapbind:body element(s), only to wsdl:part element(s) that have been defined using the type attribute. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2211 A MESSAGE described with an rpc-literal binding MUST NOT have the xsi:nil attribute with a value of "1" or "true" on the part accessors. =head2 R2207 A wsdl:message in a DESCRIPTION MAY contain wsdl:parts that use the elements attribute provided those wsdl:parts are not referred to by a soapbind:body in an rpc-literal binding. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2204 A document-literal binding in a DESCRIPTION MUST refer, in each of its soapbind:body element(s), only to wsdl:part element(s) that have been defined using the element attribute. SOAP::WSDL has no means of generating WSDL definitions. Note: SOAP::WSDL requires that a DESCRIPTION confirms to these rules. =head2 R2208 A binding in a DESCRIPTION MAY contain soapbind:header element(s) that refer to wsdl:parts in the same wsdl:message that are referred to by its soapbind:body element(s). =head2 R2205 A wsdl:binding in a DESCRIPTION MUST refer, in each of its soapbind:header, soapbind:headerfault and soapbind:fault elements, only to wsdl:part element(s) that have been defined using the element attribute. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2209 A wsdl:binding in a DESCRIPTION SHOULD bind every wsdl:part of a wsdl:message in the wsdl:portType to which it refers to one of soapbind:body, soapbind:header, soapbind:fault or soapbind:headerfault. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2206 A wsdl:message in a DESCRIPTION containing a wsdl:part that uses the element attribute MUST refer, in that attribute, to a global element declaration. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2302 A DESCRIPTION MAY use the parameterOrder attribute of an wsdl:operation element to indicate the return value and method signatures as a hint to code generators. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2303 A DESCRIPTION MUST NOT use Solicit-Response and Notification type operations in a wsdl:portType definition. =head2 R2304 A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note: SOAP::WSDL requires that a DESCRIPTION confirms to these rules. =head2 R2305 A wsdl:portType in a DESCRIPTION MUST be constructed so that the parameterOrder attribute, if present, omits at most 1 wsdl:part from the output message. =head2 R2306 A wsdl:message in a DESCRIPTION MUST NOT specify both type and element attributes on the same wsdl:part. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2401 A wsdl:binding element in a DESCRIPTION MUST use WSDL SOAP Binding as defined in WSDL 1.1 Section 3. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2701 The wsdl:binding element in a DESCRIPTION MUST be constructed so that its soapbind:binding child element specifies the transport attribute. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2702 A wsdl:binding element in a DESCRIPTION MUST specify the HTTP transport protocol with SOAP binding. Specifically, the transport attribute of its soapbind:binding child MUST have the value "http://schemas.xmlsoap.org/soap/http". SOAP::WSDL has no means of generating WSDL definitions. =head2 R2705 A wsdl:binding in a DESCRIPTION MUST use either be a rpc-literal binding or a document-literal binding. SOAP::WSDL has no means of generating WSDL definitions. Note: SOAP::WSDL does not support rpc-literal bindings yet. =head2 R2706 A wsdl:binding in a DESCRIPTION MUST use the value of "literal" for the use attribute in all soapbind:body, soapbind:fault, soapbind:header and soapbind:headerfault elements. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2707 A wsdl:binding in a DESCRIPTION that contains one or more soapbind:body, soapbind:fault, soapbind:header or soapbind:headerfault elements that do not specify the use attribute MUST be interpreted as though the value "literal" had been specified in each case. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2709 A wsdl:portType in a DESCRIPTION MAY have zero or more wsdl:bindings that refer to it, defined in the same or other WSDL documents. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2710 The operations in a wsdl:binding in a DESCRIPTION MUST result in wire signatures that are different from one another. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2711 A DESCRIPTION SHOULD NOT have more than one wsdl:port with the same value for the location attribute of the soapbind:address element. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2714 For one-way operations, an INSTANCE MUST NOT return a HTTP response that contains a SOAP envelope. Specifically, the HTTP response entity-body must be empty. SOAP::WSDL does not act as a server, yet. =head2 R2727 For one-way operations, a CONSUMER MUST NOT interpret a successful HTTP response status code (i.e., 2xx) to mean the message is valid or that the receiver would process it. SOAP::WSDL regards a successful HTTP status code for a one-way operation as an acknowledgement of the RECEIVER having receive (not processed!) the message. SOAP::WSDL makes no assumptions about the processing of SOAP messages, but higher level clients may do. =head2 R2716 A document-literal binding in a DESCRIPTION MUST NOT have the namespace attribute specified on contained soapbind:body, soapbind:header, soapbind:headerfault and soapbind:fault elements. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2717 An rpc-literal binding in a DESCRIPTION MUST have the namespace attribute specified, the value of which MUST be an absolute URI, on contained soapbind:body elements. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2726 An rpc-literal binding in a DESCRIPTION MUST NOT have the namespace attribute specified on contained soapbind:header, soapbind:headerfault and soapbind:fault elements. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2718 A wsdl:binding in a DESCRIPTION MUST have the same set of wsdl:operations as the wsdl:portType to which it refers SOAP::WSDL has no means of generating WSDL definitions. =head2 R2719 A wsdl:binding in a DESCRIPTION MAY contain no soapbind:headerfault elements if there are no known header faults. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2740 A wsdl:binding in a DESCRIPTION SHOULD contain a soapbind:fault describing each known fault. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2741 A wsdl:binding in a DESCRIPTION SHOULD contain a soapbind:headerfault describing each known header fault. SOAP::WSDL has no means of generating WSDL definitions. =head2 R2743 A MESSAGE MAY contain the details of a header processing related fault in a SOAP header block that is not described by a wsdl:headerfault element in the corresponding WSDL description. =head2 R2720 A wsdl:binding in a DESCRIPTION MUST use the attribute named part with a schema type of "NMTOKEN" on all contained soapbind:header and soapbind:headerfault elements. =head2 R2749 A wsdl:binding in a DESCRIPTION MUST NOT use the attribute named parts on contained soapbind:header and soapbind:headerfault elements. =head2 R2721 A wsdl:binding in a DESCRIPTION MUST have the name attribute specified on all contained soapbind:fault elements. =head2 R2754 In a DESCRIPTION, the value of the name attribute on a soapbind:fault element MUST match the value of the name attribute on its parent wsdl:fault element. =head2 R2722 A wsdl:binding in a DESCRIPTION MAY specify the use attribute on contained soapbind:fault elements. =head2 R2723 If in a wsdl:binding in a DESCRIPTION the use attribute on a contained soapbind:fault element is present, its value MUST be "literal". =head2 R2728 A wsdl:binding in a DESCRIPTION that omits the use attribute on a contained soapbind:fault element MUST be interpreted as though use="literal" had been specified. =head2 R2724 If an INSTANCE receives a message that is inconsistent with its WSDL description, it SHOULD generate a soap:Fault with a faultcode of "Client", unless a "MustUnderstand" or "VersionMismatch" fault is generated. =head2 R2725 If an INSTANCE receives a message that is inconsistent with its WSDL description, it MUST check for "VersionMismatch", "MustUnderstand" and "Client" fault conditions in that order. =head2 R2729 A MESSAGE described with an rpc-literal binding that is a response message MUST have a wrapper element whose name is the corresponding wsdl:operation name suffixed with the string "Response". =head2 R2735 A MESSAGE described with an rpc-literal binding MUST place the part accessor elements for parameters and return value in no namespace. =head2 R2737 A MESSAGE described with an rpc-literal binding MUST namespace qualify the children of part accessor elements for the parameters and the return value with the targetNamespace in which their types are defined. =head2 R2738 A MESSAGE MUST include all soapbind:headers specified on a wsdl:input or wsdl:output of a wsdl:operation of a wsdl:binding that describes it. =head2 R2739 A MESSAGE MAY contain SOAP header blocks that are not described in the wsdl:binding that describes it. =head2 R2753 A MESSAGE containing SOAP header blocks that are not described in the appropriate wsdl:binding MAY have the mustUnderstand attribute on such SOAP header blocks set to '1'. =head2 R2751 The order of soapbind:header elements in soapbind:binding sections of a DESCRIPTION MUST be considered independent of the order of SOAP header blocks in the message. =head2 R2752 A MESSAGE MAY contain more than one instance of each SOAP header block for each soapbind:header element in the appropriate child of soapbind:binding in the corresponding description. =head2 R2801 A DESCRIPTION MUST use XML Schema 1.0 Recommendation as the basis of user defined datatypes and structures. =head2 R3100 REGDATA of type uddi:bindingTemplate representing a conformant INSTANCE MUST contain the uddi:accessPoint element. =head2 R3002 REGDATA of type uddi:tModel representing a conformant Web service type MUST use WSDL as the description language. =head2 R3003 REGDATA of type uddi:tModel representing a conformant Web service type MUST be categorized using the uddi:types taxonomy and a categorization of "wsdlSpec". =head2 R3010 REGDATA of type uddi:tModel representing a conformant Web service type MUST follow V1.08 of the UDDI Best Practice for Using WSDL in a UDDI Registry. =head2 R3011 The wsdl:binding that is referenced by REGDATA of type uddi:tModel MUST itself conform to the Profile. =head2 R5001 If an INSTANCE requires the use of HTTPS, the location attribute of the soapbind:address element in its wsdl:port description MUST be a URI whose scheme is "https"; otherwise it MUST be a URI whose scheme is "http". SOAP::WSDL has no means of generating WSDL definitions. =head1 LICENSE AND COPYRIGHT This file contains quotes from L. To these quotes, the legal notice from the document source applies. Rest of this file: Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 562 $ $LastChangedBy: kutterma $ $Id: WS_I.pod 562 2008-02-22 20:32:17Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Manual/WS_I.pod $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Port.pm010064400017500001750000000003651361135215300155130ustar00scottscottpackage SOAP::WSDL::Port; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %binding_of :ATTR(:name :default<()>); my %address_of :ATTR(:name
:default<()>); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/Transport004075500017500001750000000000001361135364200161515ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Transport/Loopback.pm010064400017500001750000000037451361135215300203220ustar00scottscottpackage SOAP::WSDL::Transport::Loopback; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'basic'; use SOAP::WSDL::Factory::Transport; our $VERSION = 3.004; # register on loading SOAP::WSDL::Factory::Transport->register( http => __PACKAGE__ ); SOAP::WSDL::Factory::Transport->register( https => __PACKAGE__ ); my %code_of :ATTR(:name :default<()>); my %status_of :ATTR(:name :default<()>); my %message_of :ATTR(:name :default<()>); my %is_success_of :ATTR(:name :default<()>); # create methods normally inherited from SOAP::Client SUBFACTORY: { no strict qw(refs); foreach my $method ( qw(code message status is_success) ) { *{ $method } = *{ "get_$method" }; } } sub send_receive { my ($self, %parameters) = @_; return $parameters{envelope}; } Class::Std::initialize(); 1; =head1 NAME SOAP::WSDL::Transport::Test - Loopback transport class for SOAP::WSDL =head1 SYNOPSIS use SOAP::WSDL::Client; use SOAP::WSDL::Transport::Loopback; my $soap = SOAP::WSDL::Client->new() $soap->get_transport->set_base_dir('.'); $soap->call('method', \%body, \%header); =head1 DESCRIPTION SOAP::WSDL::Transport::Loopback is a loopback test transport backend for SOAP::WSDL. When SOAP::WSDL::Transport::Loopback is used as transport backend, the request is returned as response. No data ever goes over the wire. This is particularly useful for testing SOAP::WSDL plugins and applications. =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 218 $ $LastChangedBy: kutterma $ $Id: HTTP.pm 218 2007-09-10 16:19:23Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $ =cutSOAP-WSDL-3.004/lib/SOAP/WSDL/Transport/HTTP.pm010064400017500001750000000060301361135215300173350ustar00scottscottpackage SOAP::WSDL::Transport::HTTP; use strict; use warnings; use base qw(LWP::UserAgent); our $VERSION = 3.004; # create methods normally inherited from SOAP::Client SUBFACTORY: { no strict qw(refs); foreach my $method ( qw(code message status is_success) ) { *{ $method } = sub { my $self = shift; return $self->{ $method } if not @_; return $self->{ $method } = shift; }; } } sub _agent { return qq[SOAP::WSDL $VERSION]; } sub send_receive { my ($self, %parameters) = @_; my ($envelope, $soap_action, $endpoint, $encoding, $content_type) = @parameters{qw(envelope action endpoint encoding content_type)}; $encoding = defined($encoding) ? lc($encoding) : 'utf-8'; $endpoint = "" if not defined($endpoint); $content_type = "text/xml; charset=$encoding" if not defined($content_type); # what's this all about? # unfortunately combination of LWP and Perl 5.6.1 and later has bug # in sending multibyte characters. LWP uses length() to calculate # content-length header and starting 5.6.1 length() calculates chars # instead of bytes. 'use bytes' in THIS file doesn't work, because # it's lexically scoped. Unfortunately, content-length we calculate # here doesn't work either, because LWP overwrites it with # content-length it calculates (which is wrong) AND uses length() # during syswrite/sysread, so we are in a bad shape anyway. # # what to do? we calculate proper content-length (using # bytelength() function from SOAP::Utils) and then drop utf8 mark # from string (doing pack with 'C0A*' modifier) if length and # bytelength are not the same # use bytes is lexically scoped my $bytelength = do { use bytes; length $envelope }; $envelope = pack('C0A*', $envelope) if length($envelope) != $bytelength; my $request = HTTP::Request->new( 'POST', $endpoint, [ 'Content-Type', "$content_type", 'Content-Length', $bytelength, 'SOAPAction', $soap_action, ], $envelope ); my $response = $self->request( $request ); $self->code( $response->code); $self->message( $response->message); $self->is_success($response->is_success); $self->status($response->status_line); return $response->content(); } 1; =pod =head1 NAME SOAP::WSDL::Transport::HTTP - Fallback http(s) transport class =head1 DESCRIPTION Provides a thin transport class used by SOAP::WSDL::Transport when SOAP::Lite is not available. =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: HTTP.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Transport/Test.pm010064400017500001750000000066721361135215300175110ustar00scottscottpackage SOAP::WSDL::Transport::Test; use strict; use warnings; use Class::Std::Fast::Storable; use SOAP::WSDL::Factory::Transport; our $VERSION = 3.004; SOAP::WSDL::Factory::Transport->register( http => __PACKAGE__ ); SOAP::WSDL::Factory::Transport->register( https => __PACKAGE__ ); my %code_of :ATTR(:name :default<()>); my %status_of :ATTR(:name :default<()>); my %message_of :ATTR(:name :default<()>); my %is_success_of :ATTR(:name :default<()>); my %base_dir_of :ATTR(:name :init_arg :default<.>); # create methods normally inherited from SOAP::Client SUBFACTORY: { no strict qw(refs); foreach my $method ( qw(code message status is_success) ) { *{ $method } = *{ "get_$method" }; } } sub send_receive { my ($self, %parameters) = @_; my ($envelope, $soap_action, $endpoint, $encoding, $content_type) = @parameters{qw(envelope action endpoint encoding content_type)}; my $filename = $soap_action; $filename =~s{ \A(:?'|") }{}xms; $filename =~s{ (:?'|")\z }{}xms; $filename =~s{ \A [^:]+ : (:? /{2})? }{}xms; $filename = join '/', $base_dir_of{ ${ $self } }, "$filename.xml"; if (not -r $filename) { warn "cannot access $filename"; $self->set_code( 500 ); $self->set_message( "Failed" ); $self->set_is_success(0); $self->set_status("500 Failed"); return; } open my $fh, '<', $filename or die "cannot open $filename: $!"; binmode $fh; my $response = <$fh>; close $fh or die "cannot close $filename: $!"; $self->set_code( 200 ); $self->set_message( "OK" ); $self->set_is_success(1); $self->set_status("200 OK"); return $response; } 1; =head1 NAME SOAP::WSDL::Transport::Test - Test transport class for SOAP::WSDL =head1 SYNOPSIS use SOAP::WSDL::Client; use SOAP::WSDL::Transport::Test; my $soap = SOAP::WSDL::Client->new() $soap->get_transport->set_base_dir('.'); $soap->call('method', \%body, \%header); =head1 DESCRIPTION SOAP::WSDL::Transport::Test is a file-based test transport backend for SOAP::WSDL. When SOAP::WSDL::Transport::Test is used as transport backend, the response is read from a XML file and the request message is discarded. This is particularly useful for testing SOAP::WSDL plugins. =head2 Filename resolution SOAP::WSDL::Transport makes up the response XML file name from the SOAPAction of the request. The following filename is used: base_dir / soap_action .xml The protocol scheme (e.g. http:) and two heading slashes (//) are stripped from the soap_action. base_dir defaults to '.' Examples: SOAPAction: http://somewhere.over.the.rainbow/webservice/webservice.asmx Filename: ./somewhere.over.the.rainbow/webservice/webservice.asmx.xml SOAPAction: uri:MyWickedService/test Filename: ./MyWickedService/test.xml =head1 METHODS =head2 set_base_dir Sets the base directory SOAP::WSDL::Transport::Test should look for response files. =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 218 $ $LastChangedBy: kutterma $ $Id: HTTP.pm 218 2007-09-10 16:19:23Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Client004075500017500001750000000000001361135364100153725ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Client/Base.pm010064400017500001750000000044531361135215200166600ustar00scottscottpackage SOAP::WSDL::Client::Base; use strict; use warnings; use base 'SOAP::WSDL::Client'; use Scalar::Util qw(blessed); our $VERSION = 3.004; sub call { my ($self, $method, $body, $header) = @_; # Treat non-objects special if (not blessed $body) { # make sure there's something sensible in our body data $body = {} if not defined $body; $body = ref $body eq 'ARRAY' ? $body : [ $body ]; my @body_from = @{ $body }; # make a copy # build list of parts as objects initialized with # parameters given my @part_from = (); foreach my $class (@{ $method->{ body }->{ parts } }) { eval "require $class" || die $@; ## no critic (ProhibitStringyEval) push @part_from, $class->new(shift(@body_from) || {}); } # it's either the first part or a list ref with all parts... $body = $#part_from ? \@part_from : $part_from[0]; } # if we have a header if (%{ $method->{ header } }) { # treat non object special - as above, but only for one if (not blessed $header) { my $class = $method->{ header }->{ parts }->[0]; eval "require $class" || die $@; ## no critic (ProhibitStringyEval) $header = $class->new($header); } } return $self->SUPER::call($method, $body, $header); } 1; __END__ =pod =head1 NAME SOAP::WSDL::Client::Base - Factory class for WSDL-based SOAP access =head1 SYNOPSIS package MySoapInterface; use SOAP::WSDL::Client::Base; __PACKAGE__->__create_methods( qw(one two three) ); 1; =head1 DESCRIPTION Factory class for creating interface classes. Should probably be renamed to SOAP::WSDL::Factory::Interface... =head1 METHODS =head2 call Abstraction layer method between the generated interfaces and L. =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: Base.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Expat004075500017500001750000000000001361135364200152365ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Expat/Message2Hash.pm010064400017500001750000000062461361135215200201250ustar00scottscott#!/usr/bin/perl package SOAP::WSDL::Expat::Message2Hash; use strict; use warnings; use base qw(SOAP::WSDL::Expat::Base); our $VERSION = 3.004; sub _initialize { my ($self, $parser) = @_; $self->{ parser } = $parser; delete $self->{ data }; # remove potential old results my $characters; my $current = {}; my $list = []; # node list my $current_part = q{}; # are we in header or body ? $self->{ data } = $current; # use "globals" for speed my ($_element, $_method, $_class, $_parser, %_attrs) = (); # no strict qw(refs); $parser->setHandlers( Start => sub { push @$list, $current; #If our element exists and is a list ref, add to it if ( exists $current->{ $_[1] } && ( ref ($current->{ $_[1] }) eq 'ARRAY') ) { push @{ $current->{ $_[1] } }, {}; $current = $current->{ $_[1] }->[-1]; } elsif ( exists $current->{ $_[1] } ) { $current->{ $_[1] } = [ $current->{ $_[1] }, {} ]; $current = $current->{ $_[1] }->[-1]; } else { $current->{ $_[1] } = {}; $current = $current->{ $_[1] }; } return; }, Char => sub { $characters .= $_[1] if $_[1] !~m{ \A \s* \z}xms; return; }, End => sub { $_element = $_[1]; # This one easily handles ignores for us, too... # return if not ref $$list[-1]; if (length $characters) { if (ref $list->[-1]->{ $_element } eq 'ARRAY') { $list->[-1]->{ $_element }->[-1] = $characters ; } else { $list->[-1]->{ $_element } = $characters; } } $characters = q{}; $current = pop @$list; # step up in object hierarchy... return; } ); return $parser; } 1; =pod =head1 NAME SOAP::WSDL::Expat::Message2Hash - Convert SOAP messages to perl hash refs =head1 SYNOPSIS my $parser = SOAP::WSDL::Expat::MessageParser->new({ class_resolver => 'My::Resolver' }); $parser->parse( $xml ); my $obj = $parser->get_data(); =head1 DESCRIPTION Real fast expat based SOAP message parser. See L for details. =head1 Bugs and Limitations =over =item * Ignores all namespaces =item * Ignores all attributes =item * Does not handle mixed content =item * The SOAP header is ignored =back =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: $ $LastChangedDate: 2007-09-10 18:19:23 +0200 (Mo, 10 Sep 2007) $ $LastChangedRevision: 218 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Expat/WSDLParser.pm010064400017500001750000000262051361135215200175760ustar00scottscottpackage SOAP::WSDL::Expat::WSDLParser; use strict; use warnings; use Carp; use SOAP::WSDL::TypeLookup; use base qw(SOAP::WSDL::Expat::Base); our $VERSION = 3.004; # # Import child elements of a WSDL / XML Schema tree into the current tree # # Set the targetNamespace of the imported nodes to $import_namespace # # SYNOPSIS # # $self->_import_children($name, $imported, $imported, $import_namespace) # sub _import_children { my ( $self, $name, $imported, $importer, $import_namespace ) = @_; my $targetNamespace = $importer->get_targetNamespace(); my $push_method = "push_$name"; my $get_method = "get_$name"; my $default_namespace = $imported->get_xmlns()->{'#default'}; no strict qw(refs); my $value_ref = $imported->$get_method(); if ($value_ref) { $value_ref = [$value_ref] if ( not ref $value_ref eq 'ARRAY' ); for ( @{$value_ref} ) { # fixup namespace - new parent may be from different namespace if ( defined($default_namespace) ) { my $xmlns = $_->get_xmlns(); # it's a hash ref, so we can just update values if ( !defined $xmlns->{'#default'} ) { $xmlns->{'#default'} = $default_namespace; } } # fixup targetNamespace, but don't override $_->set_targetNamespace($import_namespace) if ( ( $import_namespace ne $targetNamespace ) && !$_->get_targetNamespace ); # update parent... $_->set_parent($importer); # push elements into importing WSDL $importer->$push_method($_); } } } sub _import_namespace_definitions { my $self = shift; my $arg_ref = shift; my $importer = $arg_ref->{importer}; my $imported = $arg_ref->{imported}; # import namespace definitions, too my $importer_ns_of = $importer->get_xmlns(); my %xmlns_of = %{$imported->get_xmlns()}; # it's a hash ref, we can just add to. # TODO: check whether URI is the better key. while ( my ( $prefix, $url ) = each %xmlns_of ) { if ( exists( $importer_ns_of->{$prefix} ) ) { # warn "$prefix already exists"; next; } $importer_ns_of->{$prefix} = $url; } } sub xml_schema_import { my $self = shift; my $schema = shift; my $parser = $self->clone(); my %attr_of = @_; my $import_namespace = $attr_of{namespace}; if ( not $attr_of{schemaLocation} ) { warn "cannot import document for namespace >$import_namespace< without location"; return; } if ( not $self->get_uri ) { die "cannot import document from namespace >$import_namespace< without base uri. Use >parse_uri< or >set_uri< to set one."; } my $uri = URI->new_abs( $attr_of{schemaLocation}, $self->get_uri() ); my $imported = $parser->parse_uri($uri); # might already be imported - parse_uri just returns in this case return if not defined $imported; $self->_import_namespace_definitions( { importer => $schema, imported => $imported, } ); for my $name (qw(type element group attribute attributeGroup)) { $self->_import_children( $name, $imported, $schema, $import_namespace ); } } sub wsdl_import { my $self = shift; my $definitions = shift; my $parser = $self->clone(); my %attr_of = @_; my $import_namespace = $attr_of{namespace}; if ( not $attr_of{location} ) { warn "cannot import document for namespace >$import_namespace< without location"; return; } if ( not $self->get_uri ) { die "cannot import document from namespace >$import_namespace< without base uri. Use >parse_uri< or >set_uri< to set one."; } my $uri = URI->new_abs( $attr_of{location}, $self->get_uri() ); my $imported = $parser->parse_uri($uri); # might already be imported - parse_uri just returns in this case return if not defined $imported; $self->_import_namespace_definitions( { importer => $definitions, imported => $imported, } ); for my $name (qw(types message binding portType service)) { $self->_import_children( $name, $imported, $definitions, $import_namespace ); } } sub _initialize { my ( $self, $parser ) = @_; # init object data $self->{parser} = $parser; delete $self->{data}; # setup local variables for keeping temp data my $characters = undef; my $current = undef; my $list = []; # node list my $elementFormQualified = 1; # default for WSDLs, schema may override # TODO skip non-XML Schema namespace tags $parser->setHandlers( Start => sub { # handle attrs as list - expat uses dual-vars for looking # up namespace information, and hash keys don't allow dual vars... my ( $parser, $localname, @attrs ) = @_; $characters = q{}; my $action = SOAP::WSDL::TypeLookup->lookup( $parser->namespace($localname), $localname ); return if not $action; if ( $action->{type} eq 'CLASS' ) { eval "require $action->{ class }"; croak $@ if ($@); my $obj = $action->{class}->new( { parent => $current, namespace => $parser->namespace($localname), defined($current) ? ( xmlns => $current->get_xmlns() ) : ()} )->init( _fixup_attrs( $parser, @attrs ) ); if ($current) { if ( defined $list->[-1] && $list->[-1]->isa('SOAP::WSDL::XSD::Schema') ) { $elementFormQualified = $list->[-1]->get_elementFormDefault() eq 'qualified'; } # inherit namespace, but don't override if ($elementFormQualified) { $obj->set_targetNamespace( $current->get_targetNamespace() ) if not $obj->get_targetNamespace(); } # push on parent's element/type list my $method = "push_$localname"; no strict qw(refs); $current->$method($obj); # remember element for stepping back push @{$list}, $current; } # set new element (step down) $current = $obj; } elsif ( $action->{type} eq 'PARENT' ) { $current->init( _fixup_attrs( $parser, @attrs ) ); } elsif ( $action->{type} eq 'METHOD' ) { my $method = $action->{method}; no strict qw(refs); # call method with # - default value ($action->{ value } if defined, # dereferencing lists # - the values of the elements Attributes hash # TODO: add namespaces declared to attributes. # Expat consumes them, so we have to re-add them here. $current->$method( defined $action->{value} ? ref $action->{value} ? @{$action->{value}} : ( $action->{value} ) : _fixup_attrs( $parser, @attrs ) ); } elsif ( $action->{type} eq 'HANDLER' ) { my $method = $self->can( $action->{method} ); $method->( $self, $current, @attrs ); } else { # TODO replace by hash lookup of known namespaces. my $namespace = $parser->namespace($localname) || q{}; my $part = $namespace eq 'http://schemas.xmlsoap.org/wsdl/' ? 'WSDL 1.1' : 'XML Schema'; warn "$part element <$localname> is not implemented yet" if ( $localname !~ m{ \A (:? annotation | documentation ) \z }xms ); } return; }, Char => sub { $characters .= $_[1]; return; }, End => sub { my ( $parser, $localname ) = @_; my $action = SOAP::WSDL::TypeLookup->lookup( $parser->namespace($localname), $localname ) || {}; if ( !defined $list->[-1] ) { $self->{data} = $current; return; } return if not( $action->{type} ); if ( $action->{type} eq 'CLASS' ) { $current = pop @{$list}; if ( defined $list->[-1] && $list->[-1]->isa('SOAP::WSDL::XSD::Schema') ) { $elementFormQualified = 1; } } elsif ( $action->{type} eq 'CONTENT' ) { my $method = $action->{method}; # normalize whitespace $characters =~ s{ ^ \s+ (.+) \s+ $ }{$1}xms; $characters =~ s{ \s+ }{ }xmsg; no strict qw(refs); $current->$method($characters); } return; } ); return $parser; } # make attrs SAX style sub _fixup_attrs { my ( $parser, @attrs ) = @_; my @attr_key_from = (); my @attr_value_from = (); while (@attrs) { push @attr_key_from, shift @attrs; push @attr_value_from, shift @attrs; } my @attrs_from; # add xmlns: attrs. expat eats them. # # add namespaces before attributes: Attributes may be namespace-qualified # push @attrs_from, map { { Name => "xmlns:$_", Value => $parser->expand_ns_prefix($_), LocalName => $_ } } $parser->new_ns_prefixes(); push @attrs_from, map { { Name => defined $parser->namespace($_) ? $parser->namespace($_) . '|' . $_ : '|' . $_, Value => shift @attr_value_from, # $attrs_of{ $_ }, LocalName => $_ } } @attr_key_from; return @attrs_from; } 1; =pod =head1 NAME SOAP::WSDL::Expat::WSDLParser - Parse WSDL files into object trees =head1 SYNOPSIS my $parser = SOAP::WSDL::Expat::WSDLParser->new(); $parser->parse( $xml ); my $obj = $parser->get_data(); =head1 DESCRIPTION WSDL parser used by SOAP::WSDL. =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: WSDLParser.pm 851 2009-05-15 22:45:18Z kutterma $ $LastChangedDate: 2009-05-16 00:45:18 +0200 (Sa, 16. Mai 2009) $ $LastChangedRevision: 851 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Expat/Base.pm010064400017500001750000000062331361135215200165210ustar00scottscottpackage SOAP::WSDL::Expat::Base; use strict; use warnings; use URI; use XML::Parser::Expat; # TODO: convert to Class::Std::Fast based class - hash based classes suck. our $VERSION = 3.004; sub new { my ($class, $arg_ref) = @_; my $self = { data => undef, }; bless $self, $class; $self->set_user_agent($arg_ref->{ user_agent }) if $arg_ref->{ user_agent }; $self->{ parsed } = $arg_ref->{ parsed } if $arg_ref->{ parsed }; return $self; } sub clone { my $self = shift; my $class = ref $self; my $clone = $class->new($self); return $clone; } sub set_uri { $_[0]->{ uri } = $_[1]; } sub get_uri { return $_[0]->{ uri }; } sub set_user_agent { $_[0]->{ user_agent } = $_[1]; } sub get_user_agent { return $_[0]->{ user_agent }; } # Mark a URI as "already parsed" sub set_parsed { my ($self, $uri) = @_; $self->{ parsed }->{ $uri } = 1; return; } # returns true if a specific URI has already been parsed sub is_parsed { my ($self, $uri) = @_; return exists $self->{ parsed }->{ $uri }; } # parse a URI. This is the preferred parsing method for WSDL files, as it's # the only one allowing automatic import resolution sub parse_uri { my $self = shift; my $uri = shift; if ($self->is_parsed($uri)){ warn "$uri already imported; ignoring it.\n"; return; } $self->set_parsed($uri); $self->set_uri( $uri ); if (not $self->{ user_agent }) { require LWP::UserAgent; $self->{ user_agent } = LWP::UserAgent->new(); } my $response = $self->{ user_agent }->get($uri); die $response->message() if $response->code() ne '200'; return $self->parse( $response->content() ); } sub parse { eval { $_[0]->_initialize( XML::Parser::Expat->new( Namespaces => 1 ) )->parse( $_[1] ); $_[0]->{ parser }->release(); }; $_[0]->{ parser }->xpcroak( $@ ) if $@; delete $_[0]->{ parser }; return $_[0]->{ data }; } sub parsefile { eval { $_[0]->_initialize( XML::Parser::Expat->new(Namespaces => 1) )->parsefile( $_[1] ); $_[0]->{ parser }->release(); }; $_[0]->{ parser }->xpcroak( $@ ) if $@; delete $_[0]->{ parser }; return $_[0]->{ data }; } # SAX-like aliases sub parse_string; *parse_string = \&parse; sub parse_file; *parse_file = \&parsefile; sub get_data { return $_[0]->{ data }; } 1; =pod =head1 NAME SOAP::WSDL::Expat::Base - Base class for XML::Parser::Expat based XML parsers =head1 DESCRIPTION Base class for XML::Parser::Expat based XML parsers. All XML::SAX::Expat based parsers in SOAP::WSDL inherit from this class. =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: $ $LastChangedDate: 2007-09-10 18:19:23 +0200 (Mo, 10 Sep 2007) $ $LastChangedRevision: 218 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Expat/MessageParser.pm010064400017500001750000000240101361135215200204010ustar00scottscott#!/usr/bin/perl package SOAP::WSDL::Expat::MessageParser; use strict; use warnings; use SOAP::WSDL::XSD::Typelib::Builtin; use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use base qw(SOAP::WSDL::Expat::Base); BEGIN { require Class::Std::Fast }; our $VERSION = 3.004; # GLOBALS my $OBJECT_CACHE_REF = Class::Std::Fast::OBJECT_CACHE_REF(); # keep track of classes loaded my %LOADED_OF = (); sub new { my ($class, $args) = @_; my $self = { class_resolver => $args->{ class_resolver }, strict => exists $args->{ strict } ? $args->{ strict } : 1, }; bless $self, $class; # could be written as && - but Devel::Cover doesn't like that if ($args->{ class_resolver }) { $self->load_classes() if ! exists $LOADED_OF{ $self->{ class_resolver } }; } return $self; } sub class_resolver { my $self = shift; if (@_) { $self->{ class_resolver } = shift; $self->load_classes() if ! exists $LOADED_OF{ $self->{ class_resolver } }; } return $self->{ class_resolver }; } sub load_classes { my $self = shift; return if $LOADED_OF{ $self->{ class_resolver } }; # requires sorting to make sub-packages load after their parent for (sort values %{ $self->{ class_resolver }->get_typemap }) { no strict qw(refs); my $class = $_; # a bad test - do you know a better one? next if $class eq '__SKIP__'; next if defined *{ "$class\::" }; # check if namespace exists # Require takes a bareword or a file name - we have to take # the filname road here... $class =~s{ :: }{/}xmsg; require "$class.pm"; ## no critic (RequireBarewordIncludes) } $LOADED_OF{ $self->{ class_resolver } } = 1; } sub _initialize { my ($self, $parser) = @_; $self->{ parser } = $parser; delete $self->{ data }; # remove potential old results delete $self->{ header }; my $characters; # Note: $current MUST be undef - it is used as sentinel # on the object stack via if (! defined $list->[-1]) # DON'T set it to anything else ! my $current = undef; my $list = []; # node list (object stack) my $path = []; # current path my $skip = 0; # skip elements my $depth = 0; my %content_check = $self->{strict} ? ( 0 => sub { die "Bad top node $_[1]" if $_[1] ne 'Envelope'; die "Bad namespace for SOAP envelope: " . $_[0]->recognized_string() if $_[0]->namespace($_[1]) ne 'http://schemas.xmlsoap.org/soap/envelope/'; $depth++; return; }, 1 => sub { $depth++; if ($_[1] eq 'Body') { if (exists $self->{ data }) { # there was header data $self->{ header } = $self->{ data }; delete $self->{ data }; $list = []; $path = []; undef $current; } } return; } ) : ( 0 => sub { $depth++ }, 1 => sub { $depth++ }, ); # use "globals" for speed my ($_prefix, $_method, $_class, $_leaf) = (); my $char_handler = sub { return if (!$_leaf); # we only want characters in leaf nodes $characters .= $_[1]; # add to characters return; # return void }; no strict qw(refs); $parser->setHandlers( Start => sub { # my ($parser, $element, %attrs) = @_; $_leaf = 1; # believe we're a leaf node until we see an end # call methods without using their parameter stack # That's slightly faster than $content_check{ $depth }->() # and we don't have to pass $_[1] to the method. # Yup, that's dirty. return &{$content_check{ $depth }} if exists $content_check{ $depth }; push @{ $path }, $_[1]; # step down in path return if $skip; # skip inside __SKIP__ # resolve class of this element $_class = $self->{ class_resolver }->get_class( $path ); if (! defined($_class) and $self->{ strict }) { die "Cannot resolve class for " . join('/', @{ $path }) . " via " . $self->{ class_resolver }; } if (! defined($_class) or ($_class eq '__SKIP__') ) { $skip = join('/', @{ $path }); $_[0]->setHandlers( Char => undef ); return; } # step down in tree (remember current) # # on the first object (after skipping Envelope/Body), $current # is undef. # We put it on the stack, anyway, and use it as sentinel when # going through the closing tags in the End handler # push @$list, $current; # cleanup. Mainly here to help profilers find the real hot spots undef $current; # cleanup $characters = q{}; # Create and set new objects using Class::Std::Fast's object cache # if possible, or blessing directly into the class in question # (circumventing constructor) here. # That's dirty, but fast. # # TODO: check whether this is faster under all perls - there's # strange benchmark results... # # The alternative would read: # $current = $_class->new({ @_[2..$#_] }); # $current = pop @{ $OBJECT_CACHE_REF->{ $_class } }; if (not defined $current) { my $o = Class::Std::Fast::ID(); $current = bless \$o, $_class; } # set attributes if there are any ATTR: { if (@_ > 2) { # die Data::Dumper::Dumper(@_[2..$#_]); my %attr = @_[2..$#_]; if (my $nil = delete $attr{nil}) { # TODO: check namespace if ($nil && $nil ne 'false') { undef $characters; last ATTR if not (%attr); } } $current->attr(\%attr); } } $depth++; # TODO: Skip content of anyType / any stuff return; }, Char => $char_handler, End => sub { pop @{ $path }; # step up in path # check __SKIP__ if ($skip) { return if $skip ne join '/', @{ $path }, $_[1]; $skip = 0; $_[0]->setHandlers( Char => $char_handler ); return; } $depth--; # we only set character values in leaf nodes if ($_leaf) { # Use dirty but fast access via global variables. # # The normal way (via method) would be this: # # $current->set_value( $characters ) if (length($characters)); # $SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType::___value ->{ $$current } = $characters if defined $characters && defined $current; # =~m{ [^\s] }xms; } # empty characters $characters = q{}; # stop believing we're a leaf node $_leaf = 0; # return if there's only one elment - can't set it in parent ;-) # but set as root element if we don't have one already. if (not defined $list->[-1]) { $self->{ data } = $current if (not exists $self->{ data }); return; }; # set appropriate attribute in last element # multiple values must be implemented in base class # TODO check if hash access is faster # $_method = "add_$_localname"; $_method = "add_$_[1]"; # # fixup XML names for perl names # $_method =~s{\.}{__}xg; $_method =~s{\-}{_}xg; $list->[-1]->$_method( $current ); $current = pop @$list; # step up in object hierarchy return; } ); return $parser; } sub get_header { return $_[0]->{ header }; } 1; =pod =head1 NAME SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees =head1 SYNOPSIS my $parser = SOAP::WSDL::Expat::MessageParser->new({ class_resolver => 'My::Resolver' }); $parser->parse( $xml ); my $obj = $parser->get_data(); =head1 DESCRIPTION Real fast expat based SOAP message parser. See L for details. =head2 Skipping unwanted items Sometimes there's unnecessary information transported in SOAP messages. To skip XML nodes (including all child nodes), just edit the type map for the message, set the type map entry to '__SKIP__', and comment out all child elements you want to skip. =head1 Bugs and Limitations =over =item * Ignores all namespaces =item * Does not handle mixed content =item * The SOAP header is ignored =back =head1 AUTHOR Replace the whitespace by @ for E-Mail Address. Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2004-2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 Repository information $Id: MessageParser.pm 851 2009-05-15 22:45:18Z kutterma $ $LastChangedDate: 2009-05-16 00:45:18 +0200 (Sa, 16. Mai 2009) $ $LastChangedRevision: 851 $ $LastChangedBy: kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $ SOAP-WSDL-3.004/lib/SOAP/WSDL/Expat/MessageStreamParser.pm010064400017500001750000000033011361135215200215550ustar00scottscott#!/usr/bin/perl package SOAP::WSDL::Expat::MessageStreamParser; use strict; use warnings; use XML::Parser::Expat; use SOAP::WSDL::Expat::MessageParser; use base qw(SOAP::WSDL::Expat::MessageParser); our $VERSION = 3.004; sub parse_start { my $self = shift; $self->{ parser } = $_[0]->_initialize( XML::Parser::ExpatNB->new( Namespaces => 1 ) ); } sub init; *init = \&parse_start; sub parse_more { $_[0]->{ parser }->parse_more( $_[1] ); } sub parse_done { $_[0]->{ parser }->parse_done(); $_[0]->{ parser }->release(); } 1; =pod =head1 NAME SOAP::WSDL::Expat::MessageStreamParser - Convert SOAP messages to custom object trees =head1 SYNOPSIS my $lwp = LWP::UserAgent->new(); my $parser = SOAP::WSDL::Expat::MessageParser->new({ class_resolver => 'My::Resolver' }); my $chunk_parser = $parser->init(); # process response while it comes in, trying to read 32k chunks. $lwp->request( $request, sub { $chunk_parser->parse_more($_[0]) } , 32468 ); $chunk_parser->parse_done(); my $obj = $parser->get_data(); =head1 DESCRIPTION ExpatNB based parser for parsing huge documents. See L for details. =head1 Bugs and Limitations See SOAP::WSDL::Expat::MessageParser =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: MessageStreamParser.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Manual.pod010064400017500001750000000214501361134503300161470ustar00scottscott=pod =head1 NAME SOAP::WSDL::Manual - Accessing WSDL based web services =head1 Accessing a WSDL-based web service =head2 Quick walk-through for the unpatient =over =item * Create WSDL bindings perl wsdl2perl.pl -b base_dir URL =item * Look what has been generated Check the results of the generator. There should be one MyInterfaces/SERVICE_NAME/PORT_NAME.pm file per port (and one directory per service). =item * Write script use MyInterfaces::SERVICE_NAME::PORT_NAME; my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new(); my $result = $service->SERVICE_METHOD(); die $result if not $result; print $result; C should give you some overview about the service's interface structure. The results of all calls to your service object's methods (except new) are objects based on SOAP::WSDL's XML schema implementation. To access the object's properties use get_NAME / set_NAME getter/setter methods with NAME corresponding to the XML tag name / the hash structure as showed in the generated pod. =item * Run script =back =head2 Instrumenting web services with interface classes SOAP::WSDL (starting from 2.00) instruments WSDL based web services with interface classes. This means that SOAP::WSDL features a code generator which creates one class for every web service you want to access. Moreover, the data types from the WSDL definitions are also wrapped into classes and returned to the user as objects. To find out which class a particular XML node should be, SOAP::WSDL uses typemaps. For every Web service, there's also a typemap created. =head2 Interface class creation To create interface classes, follow the steps above. If this works fine for you, skip the next paragraphs. If not, read on. The steps to instrument a web service with SOAP::WSDL perl bindings (in detail) are as follows: =over =item * Gather web service information You'll need to know at least a URL pointing to the web service's WSDL definition. If you already know more - like which methods the service provides, or how the XML messages look like, that's fine. All these things will help you later. =item * Create WSDL bindings perl wsdl2perl.pl -b base_dir URL This will generate the perl bindings in the directory specified by base_dir. For more options, see L - you may want to specify class prefixes for XML type and element classes, type maps and interface classes, and you may even want to add custom typemap elements. =item * Check the result There should be a bunch of classes for types (in the MyTypes:: namespace by default), elements (in MyElements::), and at least one typemap (in MyTypemaps::) and one or more interface classes (in MyInterfaces::). If you don't already know the details of the web service you're going to instrument, it's now time to read the perldoc of the generated interface classes. It will tell you what methods each service provides, and which parameters they take. If the WSDL definition is informative about what these methods do, the included perldoc will be, too - if not, blame the web service author. =item * Write a perl script (or module) accessing the web service. use MyInterfaces::SERVICE_NAME::PORT_NAME; my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new(); my $result = $service->SERVICE_METHOD(); die $result if not $result; print $result; The above handling of errors ("die $result if not $result") may look a bit strange - it is due to the nature of the L objects SOAP::WSDL uses for signalling failure. These objects are false in boolean context, but serialize to their XML structure on stringification. You may, of course, access individual fault properties, too. To get a list of fault properties, see L =back =head2 Adding missing information Sometimes, WSDL definitions are incomplete. In most of these cases, proper fault definitions are missing. This means that though the specification says nothing about it, Fault messages include extra elements in the EdetailE section, or errors are even indicated by non-fault messages. There are two steps you need to perform for adding additional information. =over =item * Provide required type classes For each extra data type used in the XML messages, a type class has to be created. It is strongly discouraged to use the same namespace for hand-written and generated classes - while generated classes may be many, you probably will only implement a few by hand. These (precious) few classes may get lost in the mass of (cheap) generated ones. Just imagine one of your co-workers (or even yourself) deleting the whole bunch and re-generating everything - oops - almost everything. You get the point. For simplicity, you probably just want to use builtin types wherever possible - you are probably not interested in whether a fault detail's error code is presented to you as a simpleType ranging from 1 to 10 (which you have to write) or as an int (which is a builtin type ready to use). Using builtin types for simpleType definitions may greatly reduce the number of additional classes you need to implement. If the extra type classes you need include EcomplexType E or Eelement /E definitions, see L and L on how to create ComplexType and Element type classes. =item * Provide a typemap snippet to wsdl2perl.pl SOAP::WSDL uses typemaps for finding out into which class' object a XML node should be transformed. Typemaps basically map the path of every XML element inside the Body tag to a perl class. Typemap snippets have to look like this (which is actually the default Fault typemap included in every generated one): ( 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyType', ); The lines are hash key - value pairs. The keys are the XPath expressions without occurrence numbers (like [1]) relative to the Body element. Namespaces are ignored. If you don't know about XPath: They are just the names of the XML tags, starting from the one inside EBodyE up to the current one joined by /. One line for every XML node is required. You may use all builtin, generated or custom type class names as values. Use wsdl2perl.pl -mi=FILE to include custom typemap snippets. Note that typemap include files for wsdl2perl.pl must evaluate to a valid perl hash - it will be imported via eval (OK, to be honest: via I, but that's almost the same...). Your extra statements are included last, so they override potential typemap statements with the same keys. =back =head1 Accessing a web service without a WSDL definition Accessing a web service without a WSDL definition is more cumbersome. There are two ways to go: =over =item * Write a WSDL definition and generate interface This is the way to go if you already are experienced in writing WSDL files. If you are not, be warned: Writing a correct WSDL is not an easy task, and writing correct WSDL files with only a text editor is almost impossible. You should definitely use a WSDL editor. The WSDL editor should support conformance checks for the WS-I Basic Profile (1.0 is preferred by SOAP::WSDL) =item * Write a typemap and class library from scratch If the web service is relatively simple, this is probably easier than first writing a WSDL definition. Besides, it can be done in perl, a language you are probably more familiar with than WSDL. L, L and L tell you how to create subclasses of XML schema types. L will tell you how to create a typemap class. =back =head1 Creating a SOAP Server Creating a SOAP server works just like creating a client - just add the C<--server> or C<-s> option to the call to C. perl wsdl2perl.pl -s -b BASE_DIR URL SOAP::WSDL currently includes classes for building a basic CGI and a mod_perl 2 based SOAP server. =head1 SEE ALSO L cooking recipes for accessing web services, altering the XML Serializer and others. L SOAP::WSDL's XML Schema implementation L The meaning of all these words L Basic client for SOAP::WSDL based interfaces L an interpreting WSDL based SOAP client =head1 LICENSE AND COPYRIGHT Copyright 2007 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/Serializer004075500017500001750000000000001361135364100162655ustar00scottscottSOAP-WSDL-3.004/lib/SOAP/WSDL/Serializer/XSD.pm010064400017500001750000000073231361135215300173370ustar00scottscott#!/usr/bin/perl -w package SOAP::WSDL::Serializer::XSD; use strict; use warnings; use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); our $VERSION = 3.004; use SOAP::WSDL::Factory::Serializer; my $SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/'; my $XML_INSTANCE_NS = 'http://www.w3.org/2001/XMLSchema-instance'; sub serialize { my ($self, $args_of_ref) = @_; my $opt = $args_of_ref->{ options }; if (not $opt->{ namespace }->{ $SOAP_NS }) { $opt->{ namespace }->{ $SOAP_NS } = 'SOAP-ENV'; } if (not $opt->{ namespace }->{ $XML_INSTANCE_NS }) { $opt->{ namespace }->{ $XML_INSTANCE_NS } = 'xsi'; } my $soap_prefix = $opt->{ namespace }->{ $SOAP_NS }; # envelope start with namespaces my $xml = qq|<$soap_prefix\:Envelope |; for my $uri ( sort { $a cmp $b } keys %{ $opt->{ namespace } } ) { my $prefix = $opt->{ namespace }->{ $uri }; $xml .= "xmlns:$prefix=\"$uri\" "; } # # add namespace for user-supplied prefix if needed $xml .= "xmlns:$opt->{prefix}=\"" . $args_of_ref->{ body }->get_xmlns() . "\" " if $opt->{prefix}; # TODO insert encoding $xml.='>'; $xml .= $self->serialize_header($args_of_ref->{ method }, $args_of_ref->{ header }, $opt); $xml .= $self->serialize_body($args_of_ref->{ method }, $args_of_ref->{ body }, $opt); $xml .= ''; return $xml; } sub serialize_header { my ($self, $method, $data, $opt) = @_; # header is optional. Leave out if there's no header data return q{} if not $data; return join ( q{}, "<$opt->{ namespace }->{ $SOAP_NS }\:Header>", blessed $data ? $data->serialize_qualified : (), "{ namespace }->{ $SOAP_NS }\:Header>", ); } sub serialize_body { my ($self, $method, $data, $opt) = @_; # TODO This one wipes out the old class' XML name globally # Fix in some more appropriate place... $data->__set_name("$opt->{prefix}:" . $data->__get_name() ) if $opt->{prefix}; # Body is NOT optional. Serialize to empty body # if we have no data. return join ( q{}, "<$opt->{ namespace }->{ $SOAP_NS }\:Body>", defined $data ? ref $data eq 'ARRAY' ? join q{}, map { blessed $_ ? $_->serialize_qualified() : () } @{ $data } : blessed $data ? $opt->{prefix} ? $data->serialize() : $data->serialize_qualified() : () : (), "{ namespace }->{ $SOAP_NS }\:Body>", ); } __END__ =pod =head1 NAME SOAP:WSDL::Serializer::XSD - Serializer for SOAP::WSDL::XSD::Typelib:: objects =head1 DESCRIPTION This is the default serializer for SOAP::WSDL::Client and Interface classes generated by SOAP::WSDL It may be used as a template for creating custom serializers. See L for details on that. =head1 METHODS =head2 serialize Creates a SOAP envelope based on the body and header arguments passed. Sets SOAP namespaces. =head2 serialize_body Serializes a message body to XML =head2 serialize_header Serializes a message header to XML =head1 LICENSE AND COPYRIGHT Copyright (c) 2007 Martin Kutter. All rights reserved. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself =head1 AUTHOR Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION $Rev: 851 $ $LastChangedBy: kutterma $ $Id: XSD.pm 851 2009-05-15 22:45:18Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Serializer/XSD.pm $ =cut SOAP-WSDL-3.004/lib/SOAP/WSDL/TypeLookup.pm010064400017500001750000000143131361135215300167000ustar00scottscottpackage SOAP::WSDL::TypeLookup; use strict; use warnings; our $VERSION = 3.004; my %TYPE_FROM = ( # wsdl: 'http://schemas.xmlsoap.org/wsdl/' => { 'import' => { type => 'HANDLER', method => 'wsdl_import', }, binding => { type => 'CLASS', class => 'SOAP::WSDL::Binding', }, definitions => { type => 'CLASS', class => 'SOAP::WSDL::Definitions', }, portType => { type => 'CLASS', class => 'SOAP::WSDL::PortType', }, message => { type => 'CLASS', class => 'SOAP::WSDL::Message', }, part => { type => 'CLASS', class => 'SOAP::WSDL::Part', }, service => { type => 'CLASS', class => 'SOAP::WSDL::Service', }, port => { type => 'CLASS', class => 'SOAP::WSDL::Port', }, operation => { type => 'CLASS', class => 'SOAP::WSDL::Operation', }, input => { type => 'CLASS', class => 'SOAP::WSDL::OpMessage', }, output => { type => 'CLASS', class => 'SOAP::WSDL::OpMessage', }, fault => { type => 'CLASS', class => 'SOAP::WSDL::OpMessage', }, types => { type => 'CLASS', class => 'SOAP::WSDL::Types', }, documentation => { type => 'CONTENT', method => 'set_documentation', } }, # soap: 'http://schemas.xmlsoap.org/wsdl/soap/' => { operation => { type => 'CLASS', class => 'SOAP::WSDL::SOAP::Operation', }, binding => { type => 'PARENT', }, body => { type => 'CLASS', class => 'SOAP::WSDL::SOAP::Body', }, header => { type => 'CLASS', class => 'SOAP::WSDL::SOAP::Header', }, address => { type => 'CLASS', class => 'SOAP::WSDL::SOAP::Address', } }, 'http://www.w3.org/2001/XMLSchema' => { 'import' => { type => 'HANDLER', method => 'xml_schema_import', }, schema => { type => 'CLASS', class => 'SOAP::WSDL::XSD::Schema', }, attribute => { type => 'CLASS', class => 'SOAP::WSDL::XSD::Attribute', }, attributeGroup => { type => 'CLASS', class => 'SOAP::WSDL::XSD::AttributeGroup', }, key => { type => 'SKIP', # not implemented yet }, keyref => { type => 'SKIP', # not implemented yet }, unique => { type => 'SKIP', # not implemented yet }, notation => { type => 'SKIP', # not implemented yet }, annotation => { type => 'CLASS', # not implemented yet class => 'SOAP::WSDL::XSD::Annotation', }, documentation => { type => 'CONTENT', method => 'set_documentation', }, appinfo => { type => 'SKIP', # not implemented yet }, description => { type => 'SKIP', # not implemented yet }, element => { type => 'CLASS', class => 'SOAP::WSDL::XSD::Element', }, simpleType => { type => 'CLASS', class => 'SOAP::WSDL::XSD::SimpleType', }, complexType => { type => 'CLASS', class => 'SOAP::WSDL::XSD::ComplexType', }, simpleContent => { type => 'METHOD', method => 'set_contentModel', value => 'simpleContent' }, complexContent => { type => 'METHOD', method => 'set_contentModel', value => 'complexContent' }, restriction => { type => 'METHOD', method => 'set_restriction', }, extension => { type => 'METHOD', method => 'set_extension', }, list => { type => 'METHOD', method => 'set_list', }, union => { type => 'METHOD', method => 'set_union', }, enumeration => { type => 'CLASS', class => 'SOAP::WSDL::XSD::Enumeration', }, group => { type => 'CLASS', class => 'SOAP::WSDL::XSD::Group', }, all => { type => 'METHOD', method => 'set_variety', value => 'all', }, choice => { type => 'METHOD', method => 'set_variety', value => 'choice', }, sequence => { type => 'METHOD', method => 'set_variety', value => 'sequence', }, value => { type => 'SKIP', }, minExclusive => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MinExclusive', }, maxExclusive => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MaxExclusive', }, minInclusive => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MinInclusive', }, maxInclusive => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MaxInclusive', }, maxLength => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MaxLength', }, minLength => { type => 'CLASS', class => 'SOAP::WSDL::XSD::MinLength', }, totalDigits => { type => 'CLASS', class => 'SOAP::WSDL::XSD::TotalDigits', }, fractionDigits => { type => 'CLASS', class => 'SOAP::WSDL::XSD::FractionDigits', }, }, ); $TYPE_FROM{ 'http://www.w3.org/2000/10/XMLSchema' } = $TYPE_FROM{ 'http://www.w3.org/2001/XMLSchema' }; sub lookup { my ($self, $namespace, $name) = @_; return $TYPE_FROM{ $namespace }->{ $name }; } 1;SOAP-WSDL-3.004/lib/SOAP/WSDL/Part.pm010064400017500001750000000025121361135215300154710ustar00scottscottpackage SOAP::WSDL::Part; use strict; use warnings; use Carp qw(croak); use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %element_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); sub serialize { my $self = shift; my $name = shift; my $data = shift; my $opt = shift; my $typelib = $opt->{ typelib } || die "No typelib"; my %ns_map = %{ $opt->{ namespace } }; my $item_name; if ($item_name = $self->get_type() ) { # resolve type my ($prefix, $localname) = split /:/ , $item_name, 2; my $type = $typelib->find_type( $ns_map{ $prefix }, $localname) or die "type $item_name , $ns_map{ $prefix } not found"; my $name = $self->get_name(); return $type->serialize( $name, $data->{ $name }, $opt ); } elsif ( $item_name = $self->get_element() ) { my ($prefix, $localname) = split /:/ , $item_name, 2; my $element = $typelib->find_element( $ns_map{ $prefix }, $localname ) or die "element $item_name , $ns_map{ $prefix } not found"; $opt->{ qualify } = 1; return $element->serialize( undef, $data->{ $element->get_name() }, $opt ); } die "Neither type nor element - don't know what to do"; } 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/OpMessage.pm010064400017500001750000000006201361135215300164440ustar00scottscottpackage SOAP::WSDL::OpMessage; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %body_of :ATTR(:name :default<[]>); my %header_of :ATTR(:name
:default<[]>); my %headerfault_of :ATTR(:name :default<[]>); my %message_of :ATTR(:name :default<()>); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/Message.pm010064400017500001750000000002771361135215300161550ustar00scottscottpackage SOAP::WSDL::Message; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %part_of :ATTR(:name :default<[]>); 1; SOAP-WSDL-3.004/lib/SOAP/WSDL/Binding.pm010064400017500001750000000005621361135215300161400ustar00scottscottpackage SOAP::WSDL::Binding; use strict; use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); our $VERSION = 3.004; my %operation_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); my %transport_of :ATTR(:name :default<()>); my %style_of :ATTR(:name