Permalink
Browse files

Filter.pm: new method negate()

In-place negate [=apply the logic operation NOT] the filter object.
  • Loading branch information...
1 parent c9e2387 commit d04bb1949ebef6ac6641da7b2bdfdb1d2b82d7d6 @marschap committed Jan 11, 2013
Showing with 38 additions and 1 deletion.
  1. +21 −1 lib/Net/LDAP/Filter.pm
  2. +17 −0 lib/Net/LDAP/Filter.pod
View
@@ -6,7 +6,7 @@ package Net::LDAP::Filter;
use strict;
-our $VERSION = '0.18';
+our $VERSION = '0.19';
# filter = "(" filtercomp ")"
# filtercomp = and / or / not / item
@@ -273,4 +273,24 @@ sub _string { # prints things of the form (<op> (<list>) ... )
die "Internal error $_[0]";
}
+sub negate {
+ my $self = shift;
+
+ %{$self} = _negate(%{$self});
+
+ $self;
+}
+
+sub _negate { # negate a filter tree
+ for ($_[0]) {
+ /^and/ and return ( 'or' => [ map { { _negate(%$_) }; } @{$_[1]} ] );
+ /^or/ and return ( 'and' => [ map { { _negate(%$_) }; } @{$_[1]} ] );
+ /^not/ and return %{$_[1]};
+ /^(present|equalityMatch|greaterOrEqual|lessOrEqual|approxMatch|substrings|extensibleMatch)/
+ and do return ( 'not' => { $_[0 ], $_[1] } );
+ }
+
+ die "Internal error $_[0]";
+}
+
1;
View
@@ -41,6 +41,23 @@ Return the filter in text form.
Print the text representation of the filter to FH, or the currently
selected output handle if FH is not given.
+=item negate ( )
+
+Logically negate/invert the filter object so that it matches the opposite
+set of entries as the original.
+
+Instead of simply negating the text form by surrounding it with the B<not>
+operator, the negation is done by recursively applying I<De Morgan's law>.
+
+Here is an example:
+
+ (|(&(cn=A)(cn=B))(|(!(cn=C))(cn=D)))
+
+gets negated to
+
+ (&(|(!(cn=A))(!(cn=B)))(&(cn=C)(!(cn=D))))
+
+
=back
=head1 FILTER SYNTAX

0 comments on commit d04bb19

Please sign in to comment.