File Coverage

blib/lib/Siebel/Srvrmgr/ListParser/Output/Tabular.pm
Criterion Covered Total %
statement 22 23 95.6
branch n/a
condition n/a
subroutine 8 9 88.8
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Siebel::Srvrmgr::ListParser::Output::Tabular;
2              
3 25     25   16813 use Moose;
  25         196110  
  25         130  
4 25     25   111952 use namespace::autoclean;
  25         992  
  25         156  
5 25     25   1592 use Carp qw(cluck);
  25         42  
  25         1436  
6 25     25   2371 use Siebel::Srvrmgr::Regexes qw(ROWS_RETURNED);
  25         39  
  25         932  
7 25     25   3341 use Siebel::Srvrmgr::Types;
  25         40  
  25         612  
8 25     25   10377 use Siebel::Srvrmgr::ListParser::Output::Tabular::Struct::Fixed;
  25         6254  
  25         1009  
9 25     25   13766 use Siebel::Srvrmgr::ListParser::Output::Tabular::Struct::Delimited;
  25         6609  
  25         13997  
10              
11             extends 'Siebel::Srvrmgr::ListParser::Output';
12              
13             with 'Siebel::Srvrmgr::ListParser::Output::ToString';
14              
15             has structure_type => (
16             is => 'ro',
17             isa => 'OutputTabularType',
18             reader => 'get_type',
19             required => 1
20             );
21              
22             has col_sep => (
23             is => 'ro',
24             isa => 'Chr',
25             reader => 'get_col_sep'
26             );
27              
28             has expected_fields => (
29             is => 'ro',
30             isa => 'ArrayRef',
31             reader => 'get_expected_fields',
32             writer => '_set_expected_fields',
33             builder => '_build_expected',
34             lazy => 1
35             );
36              
37             has known_types => (
38             is => 'ro',
39             isa => 'HashRef[Str]',
40             reader => 'get_known_types',
41             default => sub {
42             {
43             fixed =>
44             'Siebel::Srvrmgr::ListParser::Output::Tabular::Struct::Fixed',
45             delimited =>
46             'Siebel::Srvrmgr::ListParser::Output::Tabular::Struct::Delimited'
47             };
48             }
49             );
50              
51             has found_header => (
52             is => 'ro',
53             isa => 'Bool',
54             reader => 'found_header',
55             writer => '_set_found_header',
56             default => 0
57             );
58              
59             sub _build_expected {
60              
61 2     2   24 confess
62             '_build_expected must be overrided by subclasses of Siebel::Srvrmgr::Output::Tabular';
63              
64             }
65              
66             sub _consume_data {
67              
68 0     0     confess
69             '_consume_data must be overrided by subclasses of Siebel::Srvrmgr::ListParser::Output::Tabular';
70              
71             }
72              
73             =pod
74              
75             =head2 parse
76              
77             The method that parses the content of C<raw_data> attribute.
78              
79             This method expects a header in the file, so all subclasses of this class.
80              
81             =cut
82              
83             override 'parse' => sub {
84              
85             my $self = shift;
86              
87             my $data_ref = $self->get_raw_data();
88              
89             confess 'Invalid data to parse'
90             unless ( ( ( ref($data_ref) ) eq 'ARRAY' )
91             and ( scalar( @{$data_ref} ) ) );
92              
93             # cleaning up, state machine should not handle the end of response from a list command
94             while (
95             ( scalar( @{$data_ref} ) > 0 )
96             and ( ( $data_ref->[ $#{$data_ref} ] eq '' )
97             or ( $data_ref->[ $#{$data_ref} ] =~ ROWS_RETURNED ) )
98             )
99             {
100              
101             pop( @{$data_ref} );
102              
103             }
104              
105             confess 'Raw data became invalid after initial cleanup'
106             unless ( @{$data_ref} );
107              
108             my $struct;
109              
110             SWITCH: {
111              
112             if ( ( $self->get_type eq 'delimited' ) and $self->get_col_sep() ) {
113              
114             $struct = $self->get_known_types()->{ $self->get_type() }->new(
115             {
116             header_cols => $self->get_expected_fields(),
117             col_sep => $self->get_col_sep()
118             }
119             );
120              
121             last SWITCH;
122              
123             }
124              
125             if ( $self->get_type() eq 'fixed' ) {
126              
127             $struct = $self->get_known_types()->{ $self->get_type() }
128             ->new( { header_cols => $self->get_expected_fields() } );
129              
130             }
131             else {
132              
133             confess "Don't know what to do with "
134             . $self->get_type()
135             . ' and column separator = '
136             . $self->get_col_sep();
137              
138             }
139              
140             }
141              
142             my $header = $struct->get_header_regex();
143             my $header_regex = qr/$header/;
144             my %parsed_lines;
145             my $line_header_regex = qr/^\-+\s/;
146              
147             foreach my $line ( @{$data_ref} ) {
148              
149             SWITCH: {
150              
151             if ( $line eq '' ) {
152              
153             # do nothing
154             last SWITCH;
155             }
156              
157             if ( $line =~ $line_header_regex )
158             { # this is the '-------' below the header
159              
160             confess 'could not defined fields pattern'
161             unless ( $struct->define_fields_pattern($line) );
162             last SWITCH;
163              
164             }
165              
166             # this is the header
167             if ( $line =~ $header_regex ) {
168              
169             $self->_set_found_header(1);
170             last SWITCH;
171              
172             }
173             else {
174              
175             my $fields_ref = $struct->get_fields($line);
176              
177             confess "Cannot continue without having fields pattern defined"
178             unless ( ( defined($fields_ref) ) and ( @{$fields_ref} ) );
179              
180             unless ( $self->_consume_data( $fields_ref, \%parsed_lines ) ) {
181              
182             confess 'Could not parse fields from line [' . $line . ']';
183              
184             }
185              
186             }
187              
188             }
189              
190             }
191              
192             confess 'failure detected while parsing: header not found'
193             unless ( $self->found_header() );
194              
195             $self->set_data_parsed( \%parsed_lines );
196             $self->set_raw_data( [] );
197              
198             return 1;
199              
200             };
201              
202             =head1 CAVEATS
203              
204             All subclasses of Siebel::Srvrmgr::ListParser::Output::Tabular expect to have both the header and trailer of executed commands in C<srvrmgr> program. Removing one or both
205             of them will result in parsing errors and probably exceptions.
206              
207             =head1 SEE ALSO
208              
209             =over
210              
211             =item *
212              
213             L<Siebel::Srvrmgr::ListParser::Output>
214              
215             =back
216              
217             =head1 AUTHOR
218              
219             Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
220              
221             =head1 COPYRIGHT AND LICENSE
222              
223             This software is copyright (c) 2012 of Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
224              
225             This file is part of Siebel Monitoring Tools.
226              
227             Siebel Monitoring Tools is free software: you can redistribute it and/or modify
228             it under the terms of the GNU General Public License as published by
229             the Free Software Foundation, either version 3 of the License, or
230             (at your option) any later version.
231              
232             Siebel Monitoring Tools is distributed in the hope that it will be useful,
233             but WITHOUT ANY WARRANTY; without even the implied warranty of
234             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
235             GNU General Public License for more details.
236              
237             You should have received a copy of the GNU General Public License
238             along with Siebel Monitoring Tools. If not, see L<http://www.gnu.org/licenses/>.
239              
240             =cut
241              
242             __PACKAGE__->meta->make_immutable;
243             1;