1
package # Hide from pause
2
Monitoring::Livestatus::Class::Base::Abstract;
6
use List::Util qw/first/;
8
use Monitoring::Livestatus::Class;
9
my $TRACE = Monitoring::Livestatus::Class->TRACE() || 0;
13
handles => [qw/table_name backend_obj/],
19
builder => 'build_mode',
22
sub build_mode { die "build_mode must be implemented in " . ref(shift) };
27
builder => 'build_operators',
33
regexp => qr/(and|or)/ix,
34
handler => '_cond_compining',
39
has 'compining_prefix' => (
42
builder => 'build_compining_prefix',
45
sub build_compining_prefix { return ''; };
53
my ( $combining_count, @statments ) = $self->_recurse_cond($cond);
55
return wantarray ? @statments : \@statments;
61
my $combining_count = shift || 0;
62
print STDERR "#IN _recurse_cond $cond $combining_count\n" if $TRACE > 9;
63
my $method = $self->_METHOD_FOR_refkind("_cond",$cond);
64
my ( $child_combining_count, @statment ) = $self->$method($cond,$combining_count);
65
$combining_count = $child_combining_count;
66
print STDERR "#OUT _recurse_cond $cond $combining_count ( $method )\n" if $TRACE > 9;
67
return ( $combining_count, @statment );
70
sub _cond_UNDEF { return ( () ); }
75
my $combining_count = shift || 0;
76
print STDERR "#IN _cond_ARRAYREF $conds $combining_count\n" if $TRACE > 9;
79
my $child_combining_count = 0;
80
my @child_statment = ();
81
my @cp_conds = @{ $conds }; # work with a copy
82
while ( my $cond = shift @cp_conds ){
83
my ( $child_combining_count, @child_statment ) = $self->_dispatch_refkind($cond, {
84
ARRAYREF => sub { $self->_recurse_cond($cond, $combining_count) },
85
HASHREF => sub { $self->_recurse_cond($cond, $combining_count) },
86
UNDEF => sub { croak "not supported : UNDEF in arrayref" },
87
SCALAR => sub { $self->_recurse_cond( { $cond => shift(@cp_conds) } , $combining_count ) },
89
push @statment, @child_statment;
90
$combining_count = $child_combining_count;
92
print STDERR "#OUT _cond_ARRAYREF $conds $combining_count\n" if $TRACE > 9 ;
93
return ( $combining_count, @statment );
99
my $combining_count = shift || 0;
100
print STDERR "#IN _cond_HASHREF $cond $combining_count\n" if $TRACE > 9 ;
101
my @all_statment = ();
102
my $child_combining_count = 0;
103
my @child_statment = ();
105
foreach my $key ( keys %{ $cond } ){
106
my $value = $cond->{$key};
110
# Child key for combining filters ( -and / -or )
111
( $child_combining_count, @child_statment ) = $self->_cond_op_in_hash($key, $value, $combining_count);
112
$combining_count = $child_combining_count;
114
$method = $self->_METHOD_FOR_refkind("_cond_hashpair",$value);
115
( $child_combining_count, @child_statment ) = $self->$method($key, $value, undef ,$combining_count);
116
$combining_count = $child_combining_count;
119
push @all_statment, @child_statment;
121
print STDERR "#OUT _cond_HASHREF $cond $combining_count\n" if $TRACE > 9;
122
return ( $combining_count, @all_statment );
125
sub _cond_hashpair_UNDEF {
127
my $key = shift || '';
129
my $operator = shift || '=';
130
print STDERR "# _cond_hashpair_SCALAR\n" if $TRACE > 9 ;
132
my $combining_count = shift || 0;
134
sprintf("%s: %s %s",$self->mode,$key,$operator)
137
return ( $combining_count, @statment );
140
sub _cond_hashpair_SCALAR {
142
my $key = shift || '';
144
my $operator = shift || '=';
145
print STDERR "# _cond_hashpair_SCALAR\n" if $TRACE > 9 ;
147
my $combining_count = shift || 0;
149
sprintf("%s: %s %s %s",$self->mode,$key,$operator,$value)
152
return ( $combining_count, @statment );
155
sub _cond_hashpair_ARRAYREF {
157
my $key = shift || '';
158
my $values = shift || [];
159
my $operator = shift || '=';
160
my $combining_count = shift || 0;
161
print STDERR "#IN _cond_hashpair_ARRAYREF $combining_count\n" if $TRACE > 9;
164
foreach my $value ( @{ $values }){
165
push @statment, sprintf("%s: %s %s %s",$self->mode,$key,$operator,$value);
168
print STDERR "#OUT _cond_hashpair_ARRAYREF $combining_count\n" if $TRACE > 9;
169
return ( $combining_count, @statment );
172
sub _cond_hashpair_HASHREF {
174
my $key = shift || '';
175
my $values = shift || {};
176
my $combining = shift || undef;
177
my $combining_count = shift || 0;
179
print STDERR "#IN Abstract::_cond_hashpair_HASHREF $combining_count\n" if $TRACE > 9;
182
foreach my $child_key ( keys %{ $values } ){
183
my $child_value = $values->{ $child_key };
185
if ( $child_key =~ /^-/ ){
186
my ( $child_combining_count, @child_statment ) = $self->_cond_op_in_hash($child_key, { $key => $child_value } , 0);
187
$combining_count += $child_combining_count;
188
push @statment, @child_statment;
189
} elsif ( $child_key =~ /^[!<>=~]/ ){
190
# Child key is a operator like:
192
# ~ match regular expression (substring match)
193
# =~ equality ignoring case
194
# ~~ regular expression ignoring case
198
# >= greater or equal
199
my $method = $self->_METHOD_FOR_refkind("_cond_hashpair",$child_value);
200
my ( $child_combining_count, @child_statment ) = $self->$method($key, $child_value,$child_key);
201
$combining_count += $child_combining_count;
202
push @statment, @child_statment;
204
my $method = $self->_METHOD_FOR_refkind("_cond_hashpair",$child_value);
205
my ( $child_combining_count, @child_statment ) = $self->$method($key, $child_value);
206
$combining_count += $child_combining_count;
207
push @statment, @child_statment;
210
print STDERR "#OUT Abstract::_cond_hashpair_HASHREF $combining_count\n" if $TRACE > 9;
211
return ( $combining_count, @statment );
214
sub _cond_op_in_hash {
216
my $operator = shift;
218
my $combining_count = shift;
219
print STDERR "#IN _cond_op_in_hash $operator $value $combining_count\n" if $TRACE > 9;
221
if ( defined $operator and $operator =~ /^-/ ){
222
$operator =~ s/^-//; # remove -
223
$operator =~ s/^\s+|\s+$//g; # remove leading/trailing space
224
$operator = 'GroupBy' if ( $operator eq 'Groupby' );
227
my $operator_config = first { $operator =~ $_->{regexp} } @{ $self->operators };
228
my $operator_handler = $operator_config->{handler};
229
if ( not ref $operator_handler ){
230
return $self->$operator_handler($operator,$value,$combining_count);
231
}elsif ( ref $operator_handler eq 'CODE' ) {
232
return $operator_handler->($self,$operator,$value,$combining_count);
235
print STDERR "#OUT _cond_op_in_hash $operator $value $combining_count\n" if $TRACE > 9;
238
sub _cond_compining {
240
my $combining = shift;
242
my $combining_count = shift || 0;
243
print STDERR "#IN _cond_compining $combining $combining_count\n" if $TRACE > 9;
247
if ( defined $combining and $combining =~ /^-/ ){
248
$combining =~ s/^-//; # remove -
249
$combining =~ s/^\s+|\s+$//g; # remove leading/trailing space
250
$combining = ucfirst( $combining );
252
my ( $child_combining_count, @child_statment )= $self->_recurse_cond($value, 0 );
253
push @statment, @child_statment;
254
if ( defined $combining ) {
255
push @statment, sprintf("%s%s: %d",
256
$self->compining_prefix,
257
ucfirst( $combining ),
258
$child_combining_count,
261
print STDERR "#OUT _cond_compining $combining $combining_count \n" if $TRACE > 9;
262
return ( $combining_count, @statment );
266
my ($self, $data) = @_;
272
# blessed objects are treated like scalars
273
$ref = (blessed $data) ? '' : ref $data;
274
$n_steps += 1 if $ref;
275
last if $ref ne 'REF';
279
my $base = $ref || (defined $data ? 'SCALAR' : 'UNDEF');
282
return $base . ('REF' x $n_steps);
285
sub _dispatch_refkind {
288
my $dispatch_table = shift;
290
my $type = $self->_refkind($value);
291
my $coderef = $dispatch_table->{$type};
293
die sprintf("No coderef for %s ( %s ) found!",$value, $type)
294
unless ( ref $coderef eq 'CODE' );
299
sub _METHOD_FOR_refkind {
301
my $prefix = shift || '';
303
my $type = $self->_refkind( $value );
304
my $method = sprintf("%s_%s",$prefix,$type);
314
Monitoring::Livestatus::Class::Base::Abstract - Base class to generate
323
Reference to context object L<Monitoring::Livestatus::Class>
327
=head2 compining_prefix
335
my $filter_obj = Monitoring::Livestatus::Class::Abstract::...->new();
336
$filter_obj->apply( { name => 'localhost' } );
337
$filter_obj->apply( { name => [ 'localhost', 'gateway' ] } );
338
$filter_obj->apply( [ { name => 'localhost' }, { name => 'gateway' } ] );
340
Returns: @statments|\@statments
342
=head1 INTERNAL METHODS
348
=item build_compining_prefix
350
=item build_operators
362
=item _cond_hashpair_SCALAR
364
=item _cond_hashpair_ARRAYREF
366
=item _cond_hashpair_HASHREF
370
=item _dispatch_refkind
372
=item _METHOD_FOR_refkind
378
See L<Monitoring::Livestatus::Class/AUTHOR> and L<Monitoring::Livestatus::Class/CONTRIBUTORS>.
380
=head1 COPYRIGHT & LICENSE
382
Copyright 2009 Robert Bohne.
384
This program is free software; you can redistribute it and/or modify it
385
under the terms of either: the GNU General Public License as published
386
by the Free Software Foundation; or the Artistic License.
388
See http://dev.perl.org/licenses/ for more information.