~ubuntu-branches/ubuntu/saucy/libmonitoring-livestatus-class-perl/saucy

« back to all changes in this revision

Viewing changes to lib/Monitoring/Livestatus/Class/Base/Abstract.pm

  • Committer: Package Import Robot
  • Author(s): Alexander Wirt
  • Date: 2012-09-23 12:52:44 UTC
  • Revision ID: package-import@ubuntu.com-20120923125244-tj2b60nma3530edj
Tags: upstream-0.3
ImportĀ upstreamĀ versionĀ 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package # Hide from pause
 
2
    Monitoring::Livestatus::Class::Base::Abstract;
 
3
 
 
4
use Moose;
 
5
use Carp;
 
6
use List::Util   qw/first/;
 
7
 
 
8
use Monitoring::Livestatus::Class;
 
9
my $TRACE = Monitoring::Livestatus::Class->TRACE() || 0;
 
10
 
 
11
has 'ctx' => (
 
12
    is => 'rw',
 
13
    handles => [qw/table_name backend_obj/],
 
14
);
 
15
 
 
16
has 'mode' => (
 
17
    is => 'ro',
 
18
    isa => 'Str',
 
19
    builder => 'build_mode',
 
20
);
 
21
 
 
22
sub build_mode { die "build_mode must be implemented in " . ref(shift) };
 
23
 
 
24
has 'operators' => (
 
25
    is      => 'ro',
 
26
    isa     => 'ArrayRef',
 
27
    builder => 'build_operators',
 
28
);
 
29
 
 
30
sub build_operators {
 
31
    return [
 
32
        {
 
33
            regexp   => qr/(and|or)/ix,
 
34
            handler => '_cond_compining',
 
35
        }
 
36
    ]
 
37
};
 
38
 
 
39
has 'compining_prefix' => (
 
40
    is => 'ro',
 
41
    isa => 'Str',
 
42
    builder => 'build_compining_prefix',
 
43
);
 
44
 
 
45
sub build_compining_prefix { return ''; };
 
46
 
 
47
 
 
48
 
 
49
sub apply {
 
50
    my $self = shift;
 
51
    my $cond = shift;
 
52
 
 
53
    my ( $combining_count, @statments ) = $self->_recurse_cond($cond);
 
54
 
 
55
    return wantarray ? @statments : \@statments;
 
56
}
 
57
 
 
58
sub _recurse_cond {
 
59
    my $self = shift;
 
60
    my $cond = shift;
 
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 );
 
68
}
 
69
 
 
70
sub _cond_UNDEF { return ( () ); }
 
71
 
 
72
sub _cond_ARRAYREF {
 
73
    my $self = shift;
 
74
    my $conds = shift;
 
75
    my $combining_count = shift || 0;
 
76
    print STDERR "#IN _cond_ARRAYREF $conds $combining_count\n" if $TRACE > 9;
 
77
    my @statment = ();
 
78
 
 
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 ) },
 
88
        });
 
89
        push @statment, @child_statment;
 
90
        $combining_count = $child_combining_count;
 
91
    }
 
92
    print STDERR "#OUT _cond_ARRAYREF $conds $combining_count\n" if $TRACE > 9 ;
 
93
    return ( $combining_count, @statment );
 
94
}
 
95
 
 
96
sub _cond_HASHREF {
 
97
    my $self = shift;
 
98
    my $cond = shift;
 
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 = ();
 
104
 
 
105
    foreach my $key ( keys %{ $cond } ){
 
106
        my $value = $cond->{$key};
 
107
        my $method ;
 
108
 
 
109
        if ( $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;
 
113
        } else{
 
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;
 
117
        }
 
118
 
 
119
        push @all_statment, @child_statment;
 
120
    }
 
121
    print STDERR "#OUT _cond_HASHREF $cond $combining_count\n" if $TRACE > 9;
 
122
    return ( $combining_count, @all_statment );
 
123
}
 
124
 
 
125
sub _cond_hashpair_UNDEF {
 
126
    my $self = shift;
 
127
    my $key = shift || '';
 
128
    my $value = shift;
 
129
    my $operator = shift || '=';
 
130
    print STDERR "# _cond_hashpair_SCALAR\n" if $TRACE > 9 ;
 
131
 
 
132
    my $combining_count = shift || 0;
 
133
    my @statment = (
 
134
        sprintf("%s: %s %s",$self->mode,$key,$operator)
 
135
    );
 
136
    $combining_count++;
 
137
    return ( $combining_count, @statment );
 
138
};
 
139
 
 
140
sub _cond_hashpair_SCALAR {
 
141
    my $self = shift;
 
142
    my $key = shift || '';
 
143
    my $value = shift;
 
144
    my $operator = shift || '=';
 
145
    print STDERR "# _cond_hashpair_SCALAR\n" if $TRACE > 9 ;
 
146
 
 
147
    my $combining_count = shift || 0;
 
148
    my @statment = (
 
149
        sprintf("%s: %s %s %s",$self->mode,$key,$operator,$value)
 
150
    );
 
151
    $combining_count++;
 
152
    return ( $combining_count, @statment );
 
153
};
 
154
 
 
155
sub _cond_hashpair_ARRAYREF {
 
156
    my $self = shift;
 
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;
 
162
 
 
163
    my @statment = ();
 
164
    foreach my $value ( @{ $values }){
 
165
        push @statment, sprintf("%s: %s %s %s",$self->mode,$key,$operator,$value);
 
166
        $combining_count++;
 
167
    }
 
168
    print STDERR "#OUT _cond_hashpair_ARRAYREF $combining_count\n" if $TRACE > 9;
 
169
    return ( $combining_count, @statment );
 
170
}
 
171
 
 
172
sub _cond_hashpair_HASHREF {
 
173
    my $self            = shift;
 
174
    my $key             = shift || '';
 
175
    my $values          = shift || {};
 
176
    my $combining       = shift || undef;
 
177
    my $combining_count = shift || 0;
 
178
 
 
179
    print STDERR "#IN Abstract::_cond_hashpair_HASHREF $combining_count\n" if $TRACE > 9;
 
180
    my @statment = ();
 
181
 
 
182
    foreach my $child_key ( keys %{ $values } ){
 
183
        my $child_value = $values->{ $child_key };
 
184
 
 
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:
 
191
            # =     equality
 
192
            # ~     match regular expression (substring match)
 
193
            # =~    equality ignoring case
 
194
            # ~~    regular expression ignoring case
 
195
            # <     less than
 
196
            # >     greater than
 
197
            # <=    less or equal
 
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;
 
203
        } else {
 
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;
 
208
        }
 
209
    }
 
210
    print STDERR "#OUT Abstract::_cond_hashpair_HASHREF $combining_count\n" if $TRACE > 9;
 
211
    return ( $combining_count, @statment );
 
212
}
 
213
 
 
214
sub _cond_op_in_hash {
 
215
    my $self            = shift;
 
216
    my $operator        = shift;
 
217
    my $value           = shift;
 
218
    my $combining_count = shift;
 
219
    print STDERR "#IN  _cond_op_in_hash $operator $value $combining_count\n" if $TRACE > 9;
 
220
 
 
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' );
 
225
    }
 
226
 
 
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);
 
233
    }
 
234
 
 
235
    print STDERR "#OUT _cond_op_in_hash $operator $value $combining_count\n" if $TRACE > 9;
 
236
    return ( 0, () );
 
237
}
 
238
sub _cond_compining {
 
239
    my $self = shift;
 
240
    my $combining = shift;
 
241
    my $value = shift;
 
242
    my $combining_count = shift || 0;
 
243
    print STDERR "#IN _cond_compining $combining $combining_count\n" if $TRACE > 9;
 
244
    $combining_count++;
 
245
    my @statment = ();
 
246
 
 
247
    if ( defined $combining and $combining =~ /^-/ ){
 
248
        $combining =~ s/^-//; # remove -
 
249
        $combining =~ s/^\s+|\s+$//g; # remove leading/trailing space
 
250
        $combining = ucfirst( $combining );
 
251
    }
 
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,
 
259
        );
 
260
    }
 
261
    print STDERR "#OUT _cond_compining $combining $combining_count \n" if $TRACE > 9;
 
262
    return ( $combining_count, @statment );
 
263
}
 
264
 
 
265
sub _refkind {
 
266
  my ($self, $data) = @_;
 
267
  my $suffix = '';
 
268
  my $ref;
 
269
  my $n_steps = 0;
 
270
 
 
271
  while (1) {
 
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';
 
276
    $data = $$data;
 
277
  }
 
278
 
 
279
  my $base = $ref || (defined $data ? 'SCALAR' : 'UNDEF');
 
280
 
 
281
 
 
282
  return $base . ('REF' x $n_steps);
 
283
}
 
284
 
 
285
sub _dispatch_refkind {
 
286
    my $self = shift;
 
287
    my $value = shift;
 
288
    my $dispatch_table = shift;
 
289
 
 
290
    my $type = $self->_refkind($value);
 
291
    my $coderef = $dispatch_table->{$type};
 
292
 
 
293
    die sprintf("No coderef for %s ( %s ) found!",$value, $type)
 
294
        unless ( ref $coderef eq 'CODE' );
 
295
 
 
296
    return $coderef->();
 
297
}
 
298
 
 
299
sub _METHOD_FOR_refkind {
 
300
    my $self = shift;
 
301
    my $prefix = shift || '';
 
302
    my $value = shift;
 
303
    my $type = $self->_refkind( $value );
 
304
    my $method = sprintf("%s_%s",$prefix,$type);
 
305
    return $method;
 
306
}
 
307
 
 
308
 
 
309
 
 
310
1;
 
311
__END__
 
312
=head1 NAME
 
313
 
 
314
Monitoring::Livestatus::Class::Base::Abstract - Base class to generate
 
315
livestatus statments
 
316
 
 
317
=head2 SYNOPSIS
 
318
 
 
319
=head1 ATTRIBUTES
 
320
 
 
321
=head2 ctx
 
322
 
 
323
Reference to context object L<Monitoring::Livestatus::Class>
 
324
 
 
325
=head2 mode
 
326
 
 
327
=head2 compining_prefix
 
328
 
 
329
=head1 METHODS
 
330
 
 
331
=head2 apply
 
332
 
 
333
Example usage:
 
334
 
 
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' } ] );
 
339
 
 
340
Returns: @statments|\@statments
 
341
 
 
342
=head1 INTERNAL METHODS
 
343
 
 
344
=over 4
 
345
 
 
346
=item build_mode
 
347
 
 
348
=item build_compining_prefix
 
349
 
 
350
=item build_operators
 
351
 
 
352
=item _execute
 
353
 
 
354
=item _recurse_cond
 
355
 
 
356
=item _cond_UNDEF
 
357
 
 
358
=item _cond_ARRAYREF
 
359
 
 
360
=item _cond_HASHREF
 
361
 
 
362
=item _cond_hashpair_SCALAR
 
363
 
 
364
=item _cond_hashpair_ARRAYREF
 
365
 
 
366
=item _cond_hashpair_HASHREF
 
367
 
 
368
=item _refkind
 
369
 
 
370
=item _dispatch_refkind
 
371
 
 
372
=item _METHOD_FOR_refkind
 
373
 
 
374
=back
 
375
 
 
376
=head1 AUTHOR
 
377
 
 
378
See L<Monitoring::Livestatus::Class/AUTHOR> and L<Monitoring::Livestatus::Class/CONTRIBUTORS>.
 
379
 
 
380
=head1 COPYRIGHT & LICENSE
 
381
 
 
382
Copyright 2009 Robert Bohne.
 
383
 
 
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.
 
387
 
 
388
See http://dev.perl.org/licenses/ for more information.
 
389
 
 
390
=cut