File Coverage

blib/lib/Tree/Simple/Visitor/LoadDirectoryTree.pm
Criterion Covered Total %
statement 59 59 100.0
branch 25 28 89.2
condition 23 26 88.4
subroutine 14 14 100.0
pod 5 5 100.0
total 126 132 95.4


line stmt bran cond sub pod time code
1             package Tree::Simple::Visitor::LoadDirectoryTree;
2              
3 1     1   17265 use strict;
  1         1  
  1         24  
4 1     1   2 use warnings;
  1         1  
  1         30  
5              
6             our $VERSION = '0.15';
7              
8 1     1   3 use File::Spec;
  1         1  
  1         16  
9 1     1   3 use Scalar::Util qw(blessed);
  1         1  
  1         88  
10              
11 1     1   3 use base qw(Tree::Simple::Visitor);
  1         1  
  1         417  
12              
13             sub new {
14 4     4 1 4032 my ($_class) = @_;
15 4   33     18 my $class = ref($_class) || $_class;
16 4         5 my $visitor = {};
17 4         4 bless($visitor, $class);
18 4         8 $visitor->_init();
19 4         21 return $visitor;
20             }
21              
22             sub _init {
23 4     4   3 my ($self) = @_;
24 4         12 $self->{sort_function} = undef;
25 4         12 $self->SUPER::_init();
26             }
27              
28             # pre-built sort functions
29             sub SORT_FILES_FIRST {
30             return sub ($$$) {
31 165     165   138 my ($path, $left, $right) = @_;
32 165         402 $left = File::Spec->catdir($path, $left);
33 165         336 $right = File::Spec->catdir($path, $right);
34 165 100 100     2028 return ((-d $left && -f $right) ? 1 : # file beats directory
    100 100        
35             (-d $right && -f $left) ? -1 : # file beats directory
36             (lc($left) cmp lc($right))) # otherwise just sort 'em
37             }
38 1     1 1 956 }
39              
40             sub SORT_DIRS_FIRST {
41             return sub ($$$) {
42 163     163   160 my ($path, $left, $right) = @_;
43 163         454 $left = File::Spec->catdir($path, $left);
44 163         389 $right = File::Spec->catdir($path, $right);
45 163 100 100     2187 return ((-d $left && -f $right) ? -1 : # directory beats file
    100 100        
46             (-d $right && -f $left) ? 1 : # directory beats file
47             (lc($left) cmp lc($right))) # otherwise just sort 'em
48             }
49 1     1 1 953 }
50              
51             sub setSortStyle {
52 5     5 1 1618 my ($self, $sort_function) = @_;
53 5 100 100     46 (defined($sort_function) && ref($sort_function) eq "CODE")
54             || die "Insufficient Arguments : sort function argument must be a subroutine reference";
55 2         5 $self->{sort_function} = $sort_function;
56             }
57              
58             sub visit {
59 9     9 1 2581 my ($self, $tree) = @_;
60 9 100 100     77 (blessed($tree) && $tree->isa("Tree::Simple"))
61             || die "Insufficient Arguments : You must supply a valid Tree::Simple object";
62             # it must be a leaf
63 5 100       14 ($tree->isLeaf()) || die "Illegal Operation : The tree must be a leaf node to load a directory";
64             # check that our directory is valid
65 4         28 my $root_dir = $tree->getNodeValue();
66 4 100 66     94 (-e $root_dir && -d $root_dir)
67             || die "Incorrect Type : The tree's node value must be a valid directory";
68             # and load it recursively
69 3         6 $self->_recursiveLoad($tree, $root_dir);
70             }
71              
72             sub _recursiveLoad {
73 18     18   21 my ($self, $t, $path) = @_;
74             # get a node filter if we have one
75 18         33 my $filter = $self->getNodeFilter();
76              
77             # get the contents of the directory
78 18 50       321 opendir(DIR, $path) || die "IO Error : Could not open directory : $!";
79             # avoid the . and .. symbolic links
80             my @dir_contents = grep {
81 18 100       174 $_ ne File::Spec->curdir() && $_ ne File::Spec->updir()
  207         749  
82             } readdir(DIR);
83 18         31 close(DIR);
84              
85             # sort them if we need to with full paths
86             @dir_contents = sort {
87 328         368 $self->{sort_function}->($path, $a, $b)
88 18 100       43 } @dir_contents if $self->{sort_function};
89              
90             # now traverse ...
91 18         26 foreach my $item (@dir_contents) {
92             # filter based on the item name
93 171 50 100     8386 $filter->($item) || next if defined($filter);
94             # get the full path for checking
95             # the item type and recursion
96 141         989 my $full_path = File::Spec->catdir($path, $item);
97 141 100       1939 if (-d $full_path) {
    50          
98 15         33 my $new_tree = $t->new($item);
99 15         339 $t->addChild($new_tree);
100 15         825 $self->_recursiveLoad($new_tree, $full_path);
101             }
102             elsif (-f $full_path) {
103 126         244 $t->addChild($t->new($item));
104             }
105             }
106             }
107              
108             1;
109              
110             __END__