File Coverage

lib/XML/Compile/SOAP/WSA.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             # Copyrights 2010-2014 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.01.
5 1     1   2508 use warnings;
  1         4  
  1         68  
6 1     1   10 use strict;
  1         3  
  1         103  
7              
8             package XML::Compile::SOAP::WSA;
9             our $VERSION = '0.93';
10              
11 1     1   8 use base 'XML::Compile::SOAP::Extension';
  1         3  
  1         1480  
12              
13             use Log::Report 'xml-compile-soap-wsa';
14              
15             use XML::Compile::WSA::Util qw/WSA10MODULE WSA09 WSA10 WSDL11WSAW/;
16             use XML::Compile::SOAP::Util qw/WSDL11/;
17             use XML::Compile::Util qw/pack_type/;
18              
19             use File::Spec ();
20             use File::Basename qw/dirname/;
21              
22             my @common_hdr_elems = qw/To From Action ReplyTo FaultTo MessageID
23             RelatesTo RetryAfter/;
24             my @wsa09_hdr_elems = (@common_hdr_elems, qw/ReplyAfter/);
25             my @wsa10_hdr_elems = (@common_hdr_elems, qw/ReferenceParameters/);
26              
27             my %versions =
28             ( '0.9' => { xsd => '20070619-wsa09.xsd', wsa => WSA09
29             , hdr => \@wsa09_hdr_elems }
30             , '1.0' => { xsd => '20080723-wsa10.xsd', wsa => WSA10
31             , hdr => \@wsa10_hdr_elems }
32             );
33              
34             my $xsddir = File::Spec->catdir((dirname dirname __FILE__), 'WSA', 'xsd');
35              
36              
37             sub init($)
38             { my ($self, $args) = @_;
39              
40             $self->SUPER::init($args);
41             my $version = $args->{version}
42             or error __x"explicit wsa_version required";
43             trace "initializing wsa $version";
44              
45             $version = '1.0' if $version eq WSA10MODULE;
46             $versions{$version}
47             or error __x"unknown wsa version {v}, pick from {vs}"
48             , v => $version, vs => [keys %versions];
49             $self->{version} = $version;
50             $self;
51             }
52              
53             #-----------
54              
55              
56             sub version() {shift->{version}}
57             sub wsaNS() {$versions{shift->{version}}{wsa}}
58              
59             # This is not uglier than the WSA specification does: if you do not
60             # specify these attributes cleanly in the WSDL specs, then everyone
61             # needs hacks.
62             # Documented in XML::Compile::SOAP::Operation
63              
64             sub XML::Compile::SOAP::Operation::wsaAction($)
65             { my ($self, $dir) = @_;
66             $dir eq 'INPUT' ? $self->{wsa}{action_input} : $self->{wsa}{action_output};
67             }
68              
69             #-----------
70              
71             sub _load_ns($$)
72             { my ($self, $schema, $fn) = @_;
73             $schema->importDefinitions(File::Spec->catfile($xsddir, $fn));
74             }
75              
76             sub wsdl11Init($$)
77             { my ($self, $wsdl, $args) = @_;
78             my $def = $versions{$self->{version}};
79              
80             my $ns = $self->wsaNS;
81             $wsdl->addPrefixes(wsa => $ns, wsaw => WSDL11WSAW);
82             $wsdl->addKeyRewrite('PREFIXED(wsa,wsaw)');
83              
84             trace "loading wsa $self->{version}";
85             $self->_load_ns($wsdl, $def->{xsd});
86             $self->_load_ns($wsdl, '20060512-wsaw.xsd');
87              
88             my $wsa_action_ns = $self->version eq '0.9' ? $ns : WSDL11WSAW;
89             $wsdl->addHook
90             ( action => 'READER'
91             , type => pack_type(WSDL11, 'tParam')
92             , after => sub
93             { my ($xml, $data, $path) = @_;
94             $data->{wsa_action} = $xml->getAttributeNS($wsa_action_ns,'Action');
95             return $data;
96             }
97             );
98              
99             # For unknown reason, the FaultDetail header is described everywhere
100             # in the docs, but missing from the schema.
101             $wsdl->importDefinitions( <<_FAULTDETAIL );
102            
103             xmlns:tns="$ns" targetNamespace="$ns"
104             elementFormDefault="qualified"
105             attributeFormDefault="unqualified">
106            
107            
108            
109            
110            
111            
112            
113            
114             _FAULTDETAIL
115              
116             $self;
117             }
118              
119             sub soap11OperationInit($$)
120             { my ($self, $op, $args) = @_;
121             my $ns = $self->wsaNS;
122              
123             $op->{wsa}{action_input} = $args->{input_def}{body}{wsa_action};
124             $op->{wsa}{action_output} = $args->{output_def}{body}{wsa_action};
125              
126             trace "adding wsa header logic";
127             my $def = $versions{$self->{version}};
128             foreach my $hdr ( @{$def->{hdr}} )
129             { $op->addHeader(INPUT => "wsa_$hdr" => "{$ns}$hdr");
130             $op->addHeader(OUTPUT => "wsa_$hdr" => "{$ns}$hdr");
131             }
132              
133             # soap11 specific
134             $op->addHeader(OUTPUT => wsa_FaultDetail => "{$ns}FaultDetail");
135             }
136             *soap12OperationInit = \&soap11OperationInit;
137              
138             sub soap11ClientWrapper($$$)
139             { my ($self, $op, $call, $args) = @_;
140             my $to = ($op->endPoints)[0];
141             my $action = $op->wsaAction('INPUT') || $op->soapAction;
142             # my $outact = $op->wsaAction('OUTPUT');
143              
144             trace "added wsa in call $to".($action ? " for $action" : '');
145             sub
146             { my $data = @_==1 ? shift : {@_};
147             $data->{wsa_To} ||= $to;
148             $data->{wsa_Action} ||= $action;
149             $call->($data);
150             # should we check that the wsa_Action in the reply is correct?
151             };
152             }
153             *soap12ClientWrapper = \&soap11ClientWrapper;
154              
155             sub soap11HandlerWrapper($$$)
156             { my ($self, $op, $cb, $args) = @_;
157             my $outact = $op->wsaAction('OUTPUT');
158             defined $outact
159             or return $cb;
160              
161             sub
162             { my $data = $cb->(@_);
163             $data->{wsa_Action} = $outact;
164             $data;
165             };
166             }
167             *soap12HandlerWrapper = \&soap11HandlerWrapper;
168              
169              
170             1;