File Coverage

blib/lib/Farly/Remove/Rule.pm
Criterion Covered Total %
statement 70 72 97.2
branch 10 14 71.4
condition n/a
subroutine 15 15 100.0
pod 3 4 75.0
total 98 105 93.3


line stmt bran cond sub pod time code
1             package Farly::Remove::Rule;
2            
3 1     1   720 use 5.008008;
  1         4  
  1         53  
4 1     1   6 use strict;
  1         2  
  1         34  
5 1     1   6 use warnings;
  1         2  
  1         40  
6 1     1   5 use Carp;
  1         4  
  1         81  
7 1     1   7 use Farly::Object::Aggregate qw(NEXTVAL);
  1         2  
  1         925  
8            
9             our $VERSION = '0.26';
10            
11             sub new {
12 1     1 1 18 my ( $class, $list ) = @_;
13            
14 1 50       4 confess "configuration Farly::Object::List required"
15             unless ( defined($list) );
16            
17 1 50       9 confess "configuration Farly::Object::List required"
18             unless ( $list->isa("Farly::Object::List") );
19            
20 1         6 my $self = {
21             FW => $list,
22             RESULT => Farly::Object::List->new(),
23             };
24 1         4 bless $self, $class;
25            
26 1         3 return $self;
27             }
28            
29 1     1 0 16 sub fw { return $_[0]->{FW} }
30 5     5 1 40 sub result { return $_[0]->{RESULT} }
31            
32             sub _removes {
33 1     1   3 my ( $self, $list ) = @_;
34            
35 1         6 my $remove = Farly::Object::List->new();
36            
37 1         6 foreach my $rule ( $list->iter() ) {
38 21 100       50 if ( $rule->has_defined('REMOVE') ) {
39 2         7 $remove->add($rule);
40             }
41             }
42            
43 1         8 return $remove;
44             }
45            
46             sub _keeps {
47 1     1   2 my ( $self, $list ) = @_;
48            
49 1         6 my $keep = Farly::Object::List->new();
50            
51 1         4 foreach my $rule ( $list->iter() ) {
52 21 100       44 if ( !$rule->has_defined('REMOVE') ) {
53 19         44 $keep->add($rule);
54             }
55             }
56            
57 1         6 return $keep;
58             }
59            
60             # convert an object into a reference object
61             sub _create_ref {
62 1     1   3 my ( $self, $object ) = @_;
63            
64 1         8 my $ref = Farly::Object::Ref->new();
65 1         6 $ref->set( 'ENTRY', $object->get('ENTRY') );
66 1         5 $ref->set( 'ID', $object->get('ID') );
67            
68 1         3 return $ref;
69             }
70            
71             sub _is_expanded {
72 1     1   4 my ( $self, $list ) = @_;
73            
74 1         7 foreach my $object ( $list->iter() ) {
75 21         55 foreach my $property ( $object->get_keys() ) {
76 197 50       409 if ( $object->get($property)->isa('Farly::Object') ) {
77 0         0 confess "an expanded rule set is required";
78             }
79             }
80             }
81             }
82            
83             sub _is_unique {
84 1     1   4 my ( $self, $id, $list ) = @_;
85            
86 1         5 foreach my $object ( $list->iter() ) {
87 21 50       51 if ( !$object->matches($id) ) {
88 0         0 die "list is not unique";
89             }
90             }
91             }
92            
93             sub _aggregate {
94 2     2   4 my ( $self, $list ) = @_;
95 2         15 my $agg = Farly::Object::Aggregate->new($list);
96 2         10 $agg->groupby( 'ENTRY', 'ID', 'LINE' );
97 2         7 return $agg;
98             }
99            
100             sub remove {
101 1     1 1 5 my ( $self, $list ) = @_;
102            
103 1         6 my $rule_id = $self->_create_ref( $list->[0] );
104            
105             # validate list
106 1         7 $self->_is_unique( $rule_id, $list );
107 1         7 $self->_is_expanded($list);
108            
109             # get the config rules
110 1         10 my $cfg_rules = Farly::Object::List->new();
111 1         5 $self->fw->matches( $rule_id, $cfg_rules );
112            
113             # remove_agg will have the list of entries to be removed
114 1         10 my $remove_agg = $self->_aggregate( $self->_removes($list) );
115            
116             # keep_agg will have the set of entries which need to be kept
117 1         6 my $keep_agg = $self->_aggregate( $self->_keeps($list) );
118            
119 1         8 my $it = $remove_agg->id_iterator();
120            
121 1         6 while ( my $id = NEXTVAL($it) ) {
122            
123             # identity of the entries which are being kept
124 2         11 my $keep_list = $keep_agg->matches($id);
125            
126             # add the entries which are being kept
127 2         11 foreach my $keep_rule ( $keep_list->iter() ) {
128            
129 2         7 $self->result->add($keep_rule);
130             }
131            
132             # add the config rule being removed
133 2         10 foreach my $object ( $cfg_rules->iter() ) {
134            
135 32 100       79 if ( $object->matches($id) ) {
136            
137 2         12 my $clone = $object->clone();
138 2         12 $clone->set( 'REMOVE', Farly::Value::String->new('RULE') );
139 2         10 $clone->delete_key('LINE');
140            
141 2         10 $self->result->add($clone);
142             }
143             }
144             }
145             }
146            
147             1;
148             __END__