File Coverage

lib/Google/Ads/SOAP/Generator/TypemapVisitor.pm
Criterion Covered Total %
statement 12 99 12.1
branch 0 42 0.0
condition 0 9 0.0
subroutine 4 7 57.1
pod 2 3 66.6
total 18 160 11.2


line stmt bran cond sub pod time code
1             # Copyright 2012, Google Inc. All Rights Reserved.
2             #
3             # Licensed under the Apache License, Version 2.0 (the "License");
4             # you may not use this file except in compliance with the License.
5             # You may obtain a copy of the License at
6             #
7             # http://www.apache.org/licenses/LICENSE-2.0
8             #
9             # Unless required by applicable law or agreed to in writing, software
10             # distributed under the License is distributed on an "AS IS" BASIS,
11             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12             # See the License for the specific language governing permissions and
13             # limitations under the License.
14             #
15             # Custom visitor for generation of typemaps based on
16             # SOAP::WSDL::Generator::Visitor::Typemap, with some overriden methods via
17             # inheritance.
18              
19             package Google::Ads::SOAP::Generator::TypemapVisitor;
20              
21 2     2   939 use strict;
  2         4  
  2         65  
22 2     2   11 use warnings;
  2         3  
  2         52  
23 2     2   10 use base qw(SOAP::WSDL::Generator::Visitor::Typemap);
  2         5  
  2         153  
24              
25 2     2   14 use Class::Std::Fast::Storable;
  2         3  
  2         21  
26              
27             sub set_typemap_entry {
28 0     0 0   my ($self, $value) = @_;
29 0           my $path = join(q{/}, @{$self->get_path()});
  0            
30 0           my $tm = $self->get_typemap();
31 0 0 0       if ($tm->{$path} && $path =~ m/Fault\/detail\/ApiExceptionFault/) {
32 0           return;
33             }
34 0           $tm->{$path} = $value;
35             }
36              
37             sub visit_XSD_Element {
38 0     0 1   my ($self, $ident, $element) = ($_[0], ident $_[0], $_[1]);
39              
40 0           my @path = @{$self->get_path()};
  0            
41 0           my $path = join '/', @path;
42 0           my $parent = $self->get_typemap()->{$path};
43              
44             # PATCH breaking cycles
45 0 0         if (scalar(@path) > 30) {
46 0           return;
47             }
48             # END PATCH
49              
50 0           $self->SUPER::visit_XSD_Element($_[1]);
51             }
52              
53             sub visit_XSD_ComplexType {
54 0     0 1   my ($self, $ident, $type) = ($_[0], ident $_[0], $_[1]);
55              
56 0           my $variety = $type->get_variety();
57 0           my $derivation = $type->get_derivation();
58 0           my $content_model = $type->get_contentModel();
59              
60 0 0 0       return if not $variety or ($content_model eq "simpleContent");
61 0 0         if (grep { $_ eq $variety } qw(all sequence choice)) {
  0            
62             # Recursively going to visit child element since the type variety is
63             # either all sequence choice.
64 0 0         if (my $type_name = $type->get_base()) {
65 0           my $subtype =
66             $self->get_definitions()->first_types()
67             ->find_type($type->expand($type_name));
68 0 0         for (@{$subtype->get_element() || []}) {
  0            
69 0           $_->_accept($self);
70             }
71             }
72              
73 0 0         for (@{$type->get_element() || []}) {
  0            
74 0           $_->_accept($self);
75             }
76             }
77              
78             # PATCH - We need to also check if the complex type has derivations and
79             # include type path for all the types that derived from it.
80 0           my $last_path_elem = pop(@{$self->get_path()});
  0            
81 0           my $def_types = $self->get_definitions()->first_types();
82 0           my $schema = @{$def_types->get_schema()}[1];
  0            
83 0           my @types = @{$schema->get_type()};
  0            
84 0           my $base_type = $type->get_name();
85              
86 0 0 0       if ( @{$self->get_path()}[0]
  0            
87 0           && @{$self->get_path()}[0] eq "ApiExceptionFault")
88             {
89 0           @{$self->get_path()}[0] = "Fault/detail/ApiExceptionFault";
  0            
90             }
91              
92 0 0         if (defined $base_type) {
93 0           my $schemas = @{$self->get_definitions()->get_types()}[0]->get_schema;
  0            
94 0           SCHEMA: foreach my $my_schema (@{$schemas}) {
  0            
95 0 0         next SCHEMA if ($my_schema->isa("SOAP::WSDL::XSD::Schema::Builtin"));
96 0           my @types = @{$my_schema->get_type()};
  0            
97 0           TYPE: foreach my $type (@types) {
98 0 0         if ($type->isa("SOAP::WSDL::XSD::ComplexType")) {
99 0           my $type_name = $type->get_name();
100 0           my $base = $type->get_base();
101 0 0         next TYPE if !$base;
102 0           $base =~ s{ .*: }{}xms;
103 0 0         if ($base eq $base_type) {
104             # Checking for infinite cycles if the type has already been mapped
105             # before we skip to the next one.
106 0           foreach my $path_elem (@{$self->get_path()}) {
  0            
107 0 0         next TYPE if $path_elem eq $last_path_elem . "[$type_name]";
108             }
109              
110             # In this case we generate a new path that includes the type name
111             # E.G. /elem1/elem2[type]
112 0 0         if ($last_path_elem =~ m/\[[^\]]+\]/) {
113 0           $last_path_elem =~ s/\[[^\]]+\]/[${type_name}]/;
114 0           push(@{$self->get_path()}, $last_path_elem);
  0            
115             } else {
116 0           push(@{$self->get_path()}, $last_path_elem . "[$type_name]");
  0            
117             }
118 0           my $typeclass = $self->get_resolver()->create_xsd_name($type);
119              
120             # Setting current typemap class before to allow it to be used from
121             # inside _accept.
122 0           $self->set_typemap_entry($typeclass);
123 0           $type->_accept($self);
124              
125             # Setting it afterwards again since accept could have touch it.
126 0           $self->set_typemap_entry($typeclass);
127 0           pop(@{$self->get_path()});
  0            
128             }
129             }
130             }
131             }
132             }
133 0           push(@{$self->get_path()}, $last_path_elem);
  0            
134             # END OF PATCH.
135              
136 0 0         return if (!$derivation);
137              
138 0 0         if ($derivation eq "restriction") {
    0          
139             # Resolving the base, getting atomic type and runnning on elements.
140 0 0         if (my $type_name = $type->get_base()) {
141 0           my $subtype =
142             $self->get_definitions()->first_types()
143             ->find_type($type->expand($type_name));
144 0 0         for (@{$subtype->get_element() || []}) {
  0            
145 0           $_->_accept($self);
146             }
147             }
148             } elsif ($derivation eq "extension") {
149             # Resolving the base, getting atomic type and runnning on elements.
150 0           while (my $type_name = $type->get_base()) {
151 0           $type =
152             $self->get_definitions()->first_types()
153             ->find_type($type->expand($type_name));
154 0 0         for (@{$type->get_element() || []}) {
  0            
155 0           $_->_accept($self);
156             }
157             }
158             }
159             }
160              
161             return 1;