File Coverage

blib/lib/Siebel/Srvrmgr/ListParser/FSA.pm
Criterion Covered Total %
statement 170 199 85.4
branch 34 46 73.9
condition 5 9 55.5
subroutine 52 61 85.2
pod 4 4 100.0
total 265 319 83.0


line stmt bran cond sub pod time code
1             package Siebel::Srvrmgr::ListParser::FSA;
2 21     21   112 use warnings;
  21         45  
  21         763  
3 21     21   110 use strict;
  21         47  
  21         450  
4 21     21   111 use Siebel::Srvrmgr;
  21         42  
  21         477  
5 21     21   397 use Siebel::Srvrmgr::Regexes qw(SRVRMGR_PROMPT);
  21         44  
  21         1176  
6 21     21   113 use Scalar::Util qw(weaken);
  21         41  
  21         970  
7              
8 21     21   109 use parent 'FSA::Rules';
  21         40  
  21         182  
9              
10             =pod
11              
12             =head1 NAME
13              
14             Siebel::Srvrmgr::ListParser::FSA - the FSA::Rules class specification for Siebel::Srvrmgr::ListParser
15              
16             =head1 SYNOPSIS
17              
18             use FSA::Rules;
19             my $fsa = Siebel::Srvrmgr::ListParser::FSA->get_fsa();
20             # do something with $fsa
21              
22             # for getting a diagram exported in your currently directory with a onliner
23             perl -MSiebel::Srvrmgr::ListParser::FSA -e "Siebel::Srvrmgr::ListParser::FSA->export_diagram"
24              
25             =head1 DESCRIPTION
26              
27             Siebel::Srvrmgr::ListParser::FSA subclasses the state machine implemented by L<FSA::Rules>, which is used by L<Siebel::Srvrmgr::ListParser> class.
28              
29             This class also have a L<Log::Log4perl> instance built in.
30              
31             =head1 EXPORTS
32              
33             Nothing.
34              
35             =head1 METHODS
36              
37             =head2 export_diagram
38              
39             Creates a PNG file with the state machine diagram in the current directory where the method was invoked.
40              
41             =cut
42              
43             sub export_diagram {
44              
45 0     0 1 0 my $fsa = get_fsa();
46              
47 0         0 my $graph = $fsa->graph( layout => 'neato', overlap => 'false' );
48 0         0 $graph->as_png('pretty.png');
49              
50 0         0 return 1;
51              
52             }
53              
54             =pod
55              
56             =head2 new
57              
58             Returns the state machine object defined for usage with a L<Siebel::Srvrmgr::ListParser> instance.
59              
60             Expects as parameter a hash table reference containing all the commands alias as keys and their respective regular expressions to detect
61             state change as values. See L<Siebel::Srvrmgr::ListParser::OutputFactory> C<get_mapping> method for details.
62              
63             =cut
64              
65             sub new {
66              
67 77     77 1 160 my $class = shift;
68 77         152 my $map_ref = shift;
69              
70 77         482 my $logger = Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser::FSA');
71              
72 77 50 33     8262 $logger->logdie('the output type mapping reference received is not valid')
73             unless ( ( defined($map_ref) ) and ( ref($map_ref) eq 'HASH' ) );
74              
75             my %params = (
76             done => sub {
77              
78 13134     13134   107381 my $self = shift;
79              
80 13134         14187 my $curr_line = shift( @{ $self->{data} } );
  13134         29190  
81              
82 13134 100       28327 if ( defined($curr_line) ) {
83              
84 13084 50 66     35092 if ( defined( $self->notes('last_command') )
85             and ( $self->notes('last_command') eq 'exit' ) )
86             {
87              
88 0         0 return 1;
89              
90             }
91             else {
92              
93 13084         245050 $self->{curr_line} = $curr_line;
94 13084         50394 return 0;
95              
96             }
97              
98             }
99             else { # no more lines to process
100              
101 50         239 return 1;
102              
103             }
104              
105             }
106 77         545 );
107              
108             my $self = $class->SUPER::new(
109             \%params,
110             no_data => {
111             do => sub {
112              
113 50     50   3738 my $logger =
114             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
115              
116 50 50       1633 if ( $logger->is_debug() ) {
117              
118 0         0 $logger->debug('Searching for useful data');
119              
120             }
121              
122             },
123             rules => [
124             greetings => sub {
125              
126 116     116   2555 my $state = shift;
127              
128 116         503 my $line = $state->machine()->{curr_line};
129              
130 116 100       842 if ( defined($line) ) {
131              
132 66         780 return ( $line =~ $map_ref->{greetings} );
133              
134             }
135             else {
136              
137 50         180 return 0;
138              
139             }
140              
141             },
142             command_submission => sub {
143              
144 104     104   911 my $state = shift;
145 104         355 my $line = $state->machine()->{curr_line};
146              
147 104 100       690 if ( defined($line) ) {
148              
149 54         331 return ( $line =~ SRVRMGR_PROMPT );
150              
151             }
152             else {
153              
154 50         194 return 0;
155              
156             }
157              
158             },
159             ],
160             message => 'Line read'
161              
162             },
163             greetings => {
164             label => 'greetings message from srvrmgr',
165             on_enter => sub {
166              
167 12     12   755 my $state = shift;
168 12         67 $state->notes( is_cmd_changed => 0 );
169 12         247 $state->notes( is_data_wanted => 1 );
170 12 50       203 $state->notes( 'create_greetings' => 1 )
171             unless ( $state->notes('greetings_created') );
172             },
173             on_exit => sub {
174              
175 12     12   274 my $state = shift;
176 12         50 $state->notes( is_data_wanted => 0 );
177              
178             },
179             rules => [
180             command_submission => sub {
181              
182 208     208   3098 my $state = shift;
183 208         507 my $line = $state->machine()->{curr_line};
184 208         1228 return ( $line =~ SRVRMGR_PROMPT );
185              
186             },
187             ],
188             message => 'prompt found'
189             },
190             end => {
191             do => sub {
192              
193 0     0   0 my $logger =
194             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
195 0         0 $logger->debug('Enterprise says bye-bye');
196              
197             },
198             rules => [
199             no_data => sub {
200 0     0   0 return 1;
201             }
202             ],
203             message => 'EOF'
204             },
205             list_comp => {
206             label => 'parses output from a list comp command',
207             on_enter => sub {
208 32     32   1732 my $state = shift;
209 32         146 $state->notes( is_cmd_changed => 0 );
210 32         546 $state->notes( is_data_wanted => 1 );
211             },
212             on_exit => sub {
213              
214 23     23   532 my $state = shift;
215 23         89 $state->notes( is_data_wanted => 0 );
216              
217             },
218             rules => [
219             command_submission => sub {
220              
221 1436     1436   21799 my $state = shift;
222 1436         3708 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
223              
224             },
225             ],
226             message => 'prompt found'
227             },
228             list_comp_types => {
229             label => 'parses output from a list comp types command',
230             on_enter => sub {
231 13     13   599 my $state = shift;
232 13         51 $state->notes( is_cmd_changed => 0 );
233 13         177 $state->notes( is_data_wanted => 1 );
234             },
235             on_exit => sub {
236              
237 11     11   292 my $state = shift;
238 11         49 $state->notes( is_data_wanted => 0 );
239              
240             },
241             rules => [
242             command_submission => sub {
243              
244 3144     3144   45162 my $state = shift;
245 3144         7594 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
246              
247             },
248             ],
249             message => 'prompt found'
250             },
251             list_params => {
252             label => 'parses output from a list params command',
253             on_enter => sub {
254 14     14   611 my $state = shift;
255 14         48 $state->notes( is_cmd_changed => 0 );
256 14         196 $state->notes( is_data_wanted => 1 );
257             },
258             on_exit => sub {
259              
260 14     14   366 my $state = shift;
261 14         51 $state->notes( is_data_wanted => 0 );
262              
263             },
264             rules => [
265             command_submission => sub {
266              
267 4452     4452   63674 my $state = shift;
268 4452         11060 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
269              
270             },
271             ],
272             message => 'prompt found'
273             },
274             list_comp_def => {
275             label => 'parses output from a list comp def command',
276             on_enter => sub {
277 25     25   1213 my $state = shift;
278 25         87 $state->notes( is_cmd_changed => 0 );
279 25         376 $state->notes( is_data_wanted => 1 );
280             },
281             on_exit => sub {
282              
283 17     17   366 my $state = shift;
284 17         59 $state->notes( is_data_wanted => 0 );
285              
286             },
287             rules => [
288             command_submission => sub {
289              
290 1273     1273   18131 my $state = shift;
291 1273         3111 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
292              
293             },
294             ],
295             message => 'prompt found'
296             },
297             list_tasks => {
298             label => 'parses output from a list tasks command',
299             on_enter => sub {
300 14     14   625 my $state = shift;
301 14         47 $state->notes( is_cmd_changed => 0 );
302 14         196 $state->notes( is_data_wanted => 1 );
303             },
304             on_exit => sub {
305              
306 14     14   303 my $state = shift;
307 14         48 $state->notes( is_data_wanted => 0 );
308              
309             },
310             rules => [
311             command_submission => sub {
312              
313 1523     1523   21826 my $state = shift;
314 1523         3726 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
315              
316             },
317             ],
318             message => 'prompt found'
319             },
320             list_procs => {
321             label => 'parses output from a list procs command',
322             on_enter => sub {
323 0     0   0 my $state = shift;
324 0         0 $state->notes( is_cmd_changed => 0 );
325 0         0 $state->notes( is_data_wanted => 1 );
326             },
327             on_exit => sub {
328              
329 0     0   0 my $state = shift;
330 0         0 $state->notes( is_data_wanted => 0 );
331              
332             },
333             rules => [
334             command_submission => sub {
335              
336 0     0   0 my $state = shift;
337 0         0 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
338              
339             },
340             ],
341             message => 'prompt found'
342             },
343             list_servers => {
344             label => 'parses output from a list servers command',
345             on_enter => sub {
346 7     7   315 my $state = shift;
347 7         30 $state->notes( is_cmd_changed => 0 );
348 7         118 $state->notes( is_data_wanted => 1 );
349             },
350             on_exit => sub {
351              
352 7     7   147 my $state = shift;
353 7         25 $state->notes( is_data_wanted => 0 );
354              
355             },
356             rules => [
357             command_submission => sub {
358              
359 56     56   839 my $state = shift;
360 56         141 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
361              
362             },
363             ],
364             message => 'prompt found'
365             },
366             list_sessions => {
367             label => 'parses output from a list sessions command',
368             on_enter => sub {
369 6     6   261 my $state = shift;
370 6         22 $state->notes( is_cmd_changed => 0 );
371 6         94 $state->notes( is_data_wanted => 1 );
372             },
373             on_exit => sub {
374              
375 6     6   135 my $state = shift;
376 6         20 $state->notes( is_data_wanted => 0 );
377              
378             },
379             rules => [
380             command_submission => sub {
381              
382 778     778   11381 my $state = shift;
383 778         1960 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
384              
385             },
386             ],
387             message => 'prompt found'
388             },
389             set_delimiter => {
390             label => 'parses output (?) from set delimiter command',
391             on_enter => sub {
392 0     0   0 my $state = shift;
393 0         0 $state->notes( is_cmd_changed => 0 );
394 0         0 $state->notes( is_data_wanted => 1 );
395             },
396             on_exit => sub {
397              
398 0     0   0 my $state = shift;
399 0         0 $state->notes( is_data_wanted => 0 );
400              
401             },
402             rules => [
403             command_submission => sub {
404              
405 0     0   0 my $state = shift;
406 0         0 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
407              
408             },
409             ],
410             message => 'prompt found'
411             },
412             load_preferences => {
413             label => 'parses output from a load preferences command',
414             on_enter => sub {
415 12     12   599 my $state = shift;
416 12         55 $state->notes( is_cmd_changed => 0 );
417 12         195 $state->notes( is_data_wanted => 1 );
418             },
419             on_exit => sub {
420              
421 11     11   248 my $state = shift;
422 11         46 $state->notes( is_data_wanted => 0 );
423              
424             },
425             rules => [
426             command_submission => sub {
427              
428 23     23   378 my $state = shift;
429 23         84 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
430              
431             },
432             ],
433             message => 'prompt found'
434             },
435             command_submission => {
436             do => sub {
437              
438 151     151   7417 my $state = shift;
439              
440 151         587 my $logger =
441             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
442 151 50       3757 if ( $logger->is_debug() ) {
443              
444 0         0 my $line = $state->notes('line');
445 0 0       0 $logger->debug( 'command_submission got [' . $line . ']' )
446             if ( defined($line) );
447              
448             }
449              
450 151         1347 $state->notes( found_prompt => 1 );
451 151         2473 my $cmd = ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT )[1];
452              
453 151 100 66     1065 if ( ( defined($cmd) ) and ( $cmd ne '' ) ) {
454              
455             # removing spaces from command
456 124         383 $cmd =~ s/^\s+//;
457 124         504 $cmd =~ s/\s+$//;
458              
459 124 50       425 $logger->debug("last_command set with '$cmd'")
460             if $logger->is_debug();
461              
462 124         1046 $state->notes( last_command => $cmd );
463 124         1910 $state->notes( is_cmd_changed => 1 );
464              
465             }
466             else {
467              
468 27 50       117 if ( $logger->is_debug() ) {
469              
470 0         0 $logger->debug('got prompt, but no command submitted');
471              
472             }
473              
474 27         231 $state->notes( last_command => '' );
475 27         392 $state->notes( is_cmd_changed => 1 );
476              
477             }
478              
479             },
480             rules => [
481             set_delimiter => sub {
482              
483 125     125   2561 my $state = shift;
484              
485 125 50       389 if ( $state->notes('last_command') =~
486             $map_ref->{set_delimiter} )
487             {
488              
489 0         0 return 1;
490              
491             }
492             else {
493              
494 125         2088 return 0;
495              
496             }
497              
498             },
499             list_comp => sub {
500              
501 125     125   1014 my $state = shift;
502              
503 125 100       473 if (
504             $state->notes('last_command') =~ $map_ref->{list_comp} )
505             {
506              
507 32         684 return 1;
508              
509             }
510             else {
511              
512 93         1589 return 0;
513              
514             }
515              
516             },
517             list_comp_types => sub {
518              
519 93     93   672 my $state = shift;
520              
521 93 100       288 if ( $state->notes('last_command') =~
522             $map_ref->{list_comp_types} )
523             {
524              
525 13         244 return 1;
526              
527             }
528             else {
529              
530 80         1268 return 0;
531              
532             }
533              
534             },
535             list_params => sub {
536              
537 80     80   583 my $state = shift;
538              
539 80 100       239 if ( $state->notes('last_command') =~
540             $map_ref->{list_params} )
541             {
542              
543 14         281 return 1;
544              
545             }
546             else {
547              
548 66         1080 return 0;
549              
550             }
551              
552             },
553             list_tasks => sub {
554              
555 66     66   488 my $state = shift;
556              
557 66 100       209 if ( $state->notes('last_command') =~
558             $map_ref->{list_tasks} )
559             {
560              
561 14         243 return 1;
562              
563             }
564             else {
565              
566 52         862 return 0;
567              
568             }
569              
570             },
571             list_procs => sub {
572              
573 52     52   403 my $state = shift;
574              
575 52 50       174 if ( $state->notes('last_command') =~
576             $map_ref->{list_procs} )
577             {
578              
579 0         0 return 1;
580              
581             }
582             else {
583              
584 52         891 return 0;
585              
586             }
587              
588             },
589             list_servers => sub {
590              
591 52     52   452 my $state = shift;
592              
593 52 100       231 if ( $state->notes('last_command') =~
594             $map_ref->{list_servers} )
595             {
596              
597 7         121 return 1;
598              
599             }
600             else {
601              
602 45         713 return 0;
603              
604             }
605              
606             },
607             list_sessions => sub {
608              
609 45     45   430 my $state = shift;
610              
611 45 100       147 if ( $state->notes('last_command') =~
612             $map_ref->{list_sessions} )
613             {
614              
615 6         107 return 1;
616              
617             }
618             else {
619              
620 39         656 return 0;
621              
622             }
623              
624             },
625             list_comp_def => sub {
626              
627 39     39   301 my $state = shift;
628              
629 39 100       126 if ( $state->notes('last_command') =~
630             $map_ref->{list_comp_def} )
631             {
632              
633 25         460 return 1;
634              
635             }
636             else {
637              
638 14         246 return 0;
639              
640             }
641              
642             },
643             load_preferences => sub {
644              
645 14     14   108 my $state = shift;
646              
647 14 100       55 if ( $state->notes('last_command') =~
648             $map_ref->{load_preferences} )
649             {
650              
651 12         242 return 1;
652              
653             }
654             else {
655              
656 2         29 return 0;
657              
658             }
659              
660             },
661             no_data => sub {
662              
663 2     2   16 my $state = shift;
664              
665 2 50       7 if ( $state->notes('last_command') eq '' ) {
666              
667 0         0 return 1;
668              
669             }
670             else {
671              
672 2         27 return 0;
673              
674             }
675              
676             },
677              
678             # add other possibilities here of list commands
679 77         10353 ],
680             message => 'command submitted'
681             }
682             );
683              
684 77         65148 $self->{data} = undef;
685 77         192 $self->{curr_line} = undef;
686              
687 77         3974 return $self;
688              
689             }
690              
691             =head2 set_data
692              
693             Set the array reference of the data to be parsed by this object.
694              
695             =cut
696              
697             sub set_data {
698              
699 50     50 1 124 my $self = shift;
700 50         211 $self->{data} = shift;
701              
702             }
703              
704             =head2 get_curr_line
705              
706             Returns a string, the current line being processed by this object.
707              
708             =cut
709              
710             sub get_curr_line {
711              
712 13134     13134 1 43037 return shift->{curr_line};
713              
714             }
715              
716             1;
717              
718             =pod
719              
720             =head1 SEE ALSO
721              
722             =over
723              
724             =item *
725              
726             L<Siebel::Srvrmgr::ListParser>
727              
728             =item *
729              
730             L<FSA::Rules>
731              
732             =back
733              
734             =head1 CAVEATS
735              
736             This class has some problems, most due the API of L<FSA::Rules>: since the state machine is a group of references to subroutines, it holds references
737             to L<Siebel::Srvrmgr::ListParser>, which basically causes circular references between the two classes.
738              
739             There is some workaround to the caused memory leaks due this configuration, but in future releases L<FSA::Rules> may be replaced to something else.
740              
741             =head1 AUTHOR
742              
743             Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
744              
745             =head1 COPYRIGHT AND LICENSE
746              
747             This software is copyright (c) 2013 of Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
748              
749             This file is part of Siebel Monitoring Tools.
750              
751             Siebel Monitoring Tools is free software: you can redistribute it and/or modify
752             it under the terms of the GNU General Public License as published by
753             the Free Software Foundation, either version 3 of the License, or
754             (at your option) any later version.
755              
756             Siebel Monitoring Tools is distributed in the hope that it will be useful,
757             but WITHOUT ANY WARRANTY; without even the implied warranty of
758             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
759             GNU General Public License for more details.
760              
761             You should have received a copy of the GNU General Public License
762             along with Siebel Monitoring Tools. If not, see <http://www.gnu.org/licenses/>.
763              
764             =cut