File Coverage

lib/WSDL/Generator/Schema.pm
Criterion Covered Total %
statement 90 92 97.8
branch 25 32 78.1
condition 1 3 33.3
subroutine 9 9 100.0
pod 3 5 60.0
total 128 141 90.7


line stmt bran cond sub pod time code
1             =pod
2              
3             =head1 NAME
4              
5             WSDL::Generator::Schema - Generate wsdl schema for WSDL::Generator
6              
7             =head1 SYNOPSIS
8              
9             use WSDL::Generator::Schema;
10             my $schema = WSDL::Generator::Schema->new('mytargetNamespace');
11             $schema->add($struct);
12             $schema->add($struct2);
13             print $schema->get->to_string;
14              
15             =cut
16             package WSDL::Generator::Schema;
17              
18 1     1   4 use strict;
  1         2  
  1         32  
19 1     1   5 use warnings::register;
  1         2  
  1         95  
20 1     1   6 use Carp;
  1         1  
  1         58  
21 1     1   5 use base qw(WSDL::Generator::Base);
  1         2  
  1         450  
22              
23             our $VERSION = '0.01';
24              
25              
26             =pod
27              
28             =head1 CONSTRUCTOR
29              
30             =head2 new($namespace)
31              
32             $namespace is optional.
33             Returns WSDL::Generator::Schema object
34              
35             =cut
36             sub new {
37 1     1 1 5 my ($class, $namespace) = @_;
38 1         4 my $self = { 'schema_namesp' => $namespace,
39             'counter' => 0 };
40 1         5 return bless $self => $class;
41             }
42              
43             =pod
44              
45             =head1 METHODS
46              
47             =head2 add($struct)
48              
49             Generate a wsdl schema for the structure sent
50              
51             =cut
52             sub add : method {
53 6     6 1 11 my ($self, $struct, $name) = @_;
54 6         7 push @{$self->{schema}}, $self->make_types($self->dumper($struct), $name);
  6         32  
55             }
56              
57             =pod
58              
59             =head2 get($namespace)
60              
61             $namespace is optional (it must be specified here or in new method).
62             Returns the Schema wsdl array of lines
63              
64             =cut
65             sub get : method {
66 1     1 1 2 my ($self, $namespace) = @_;
67 1 50       5 $self->{schema_namesp} = $namespace if (defined $namespace);
68 1 50       5 unless ($self->{schema}) {
69 0         0 carp 'No schema defined';
70 0         0 return 0;
71             }
72 1         7 my $schema = $self->get_wsdl_element( { wsdl_type => 'TYPES',
73             %$self,
74             } );
75 1         7 return $schema;
76             }
77              
78              
79             #
80             # Create wsdl types declations
81             #
82             sub make_types {
83 13     13 0 17 my $self = shift;
84 13         13 my $struct = shift;
85 13   33     29 my $name = shift || 'myelement'.$self->{counter}++;
86 13         18 my @wsdl = ();
87 13 100       44 if ($struct->{type} eq 'SCALAR' ) {
    100          
    50          
88 2         2 push @wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ELEMENT',
  2         15  
89             name => $name,
90             type => 'string',
91             } )};
92             }
93             elsif ($struct->{type} eq 'HASHREF' ) {
94 6         7 my @sub_wsdl = ();
95 6         7 foreach my $key ( keys %{$struct->{value}} ) {
  6         16  
96 16 100       43 if ($struct->{value}->{$key}->{type} eq 'SCALAR') {
97 13         15 push @sub_wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ELEMENT',
  13         67  
98             type => 'string',
99             name => $key,
100             min_occur => $struct->{value}->{$key}->{min_occur} } )};
101             }
102             else {
103 3         7 my $type = 'myelement'.$self->{counter}++;
104 3         10 push @sub_wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ELEMENT',
  3         19  
105             type => "xsdl:$type",
106             name => $key,
107             min_occur => $struct->{value}->{$key}->{min_occur} } )};
108 3         12 push @wsdl, $self->make_types($struct->{value}->{$key}, $type);
109             }
110             }
111 6         10 push @wsdl, @{$self->get_wsdl_element( { wsdl_type => 'HASHREF',
  6         26  
112             name => $name,
113             elements => \@sub_wsdl,
114             } )};
115             }
116             elsif ($struct->{type} eq 'ARRAYREF') {
117 5         12 $struct->{value} = [ array_reduction($struct->{value}) ];
118 5         22 my $type = $struct->{value}->[0]->{type};
119 5 100       17 if ($type eq 'SCALAR') {
    100          
    50          
120 1         7 push @wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ARRAYREF',
  1         7  
121             name => $name,
122             max_occur => 'unbounded',
123             type => 'string',
124             } )};
125             }
126             elsif ($type eq 'ARRAYREF') {
127 1         4 my $new_name = 'myelement'.$self->{counter}++;
128 1         8 push @wsdl, $self->make_types($struct->{value}->[0], $new_name);
129 1         2 push @wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ARRAYREF',
  1         7  
130             name => $name,
131             max_occur => 'unbounded',
132             type => "xsdl:$new_name",
133             } )};
134             }
135             elsif ($type eq 'HASHREF') {
136 3         9 my $new_name = 'myelement'.$self->{counter}++;
137 3         11 push @wsdl, $self->make_types($struct->{value}->[0], $new_name);
138 3         4 push @wsdl, @{$self->get_wsdl_element( { wsdl_type => 'ARRAYREF',
  3         18  
139             name => $name,
140             max_occur => 'unbounded',
141             type => "xsdl:$new_name",
142             } )};
143             }
144             }
145 13         91 return @wsdl;
146             }
147              
148              
149             #
150             # Merge all elements of an array into 1 element
151             # Array of scalar => 1 scalar
152             # Array of hashref => 1 hashref containing all keys + a counter for each
153             sub array_reduction {
154 18     18 0 18 my $array = shift;
155 18 100       43 return $array->[0] if (@$array == 1);
156 10         15 my $first_type = $array->[0]->{type};
157 10         13 my $branch = {};
158 10 100       31 if ($first_type eq 'SCALAR') {
    100          
    50          
159 6         11 $branch->{type} = 'SCALAR';
160 6         12 $branch->{value} = $array->[0]->{value};
161             }
162             elsif ($first_type eq 'ARRAYREF') {
163 1         3 my @fields = ();
164 1         3 foreach my $element (@$array) {
165 3 50       9 $element->{type} eq 'ARRAYREF' or croak "Expected arrayrefs only in the array";
166 3         62 my $i = 0;
167 3         4 foreach my $sub_element (@{$element->{value}}) {
  3         8  
168 8         8 push @{$fields[$i++]}, $sub_element;
  8         20  
169             }
170             }
171 1         3 foreach my $element (@fields) {
172 4         19 $element = array_reduction($element);
173             }
174 1         4 $branch->{value} = \@fields;
175 1         3 $branch->{type} = 'ARRAYREF';
176             }
177             elsif ($first_type eq 'HASHREF') {
178 3         4 my %fields = ();
179 3         46 foreach my $element (@$array) {
180 6 50       14 $element->{type} eq 'HASHREF' or croak "Expected hashrefs only in the array";
181 6         6 foreach my $key (keys %{$element->{value}}) {
  6         16  
182 12         11 push @{$fields{$key}}, $element->{value}->{$key};
  12         38  
183             }
184             }
185             # Calculates min_occur
186 3         9 foreach my $key (keys %fields) {
187 9 100       9 my $min_occur = (@{$fields{$key}} == scalar @$array) ? 1 : 0;
  9         21  
188 9         19 $fields{$key} = array_reduction($fields{$key});
189 9         30 $fields{$key}->{min_occur} = $min_occur;
190             }
191 3         7 $branch->{value} = \%fields;
192 3         5 $branch->{type} = 'HASHREF';
193             }
194 10         26 return $branch;
195             }
196              
197              
198              
199              
200             1;
201              
202             =pod
203              
204             =head1 SEE ALSO
205              
206             WSDL::Generator
207              
208             =head1 AUTHOR
209              
210             "Pierre Denis"
211              
212             =head1 COPYRIGHT
213              
214             Copyright (C) 2001, Fotango Ltd - All rights reserved.
215             This is free software. This software may be modified and/or distributed under the same terms as Perl itself.
216              
217             =cut