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   61019 use strict;
  1         11  
  1         24  
4 1     1   4 use warnings;
  1         2  
  1         31  
5              
6             our $VERSION = '0.16';
7              
8 1     1   5 use File::Spec;
  1         1  
  1         36  
9 1     1   5 use Scalar::Util qw(blessed);
  1         2  
  1         57  
10              
11 1     1   5 use base qw(Tree::Simple::Visitor);
  1         2  
  1         444  
12              
13             sub new {
14 4     4 1 4641 my ($_class) = @_;
15 4   33     17 my $class = ref($_class) || $_class;
16 4         7 my $visitor = {};
17 4         6 bless($visitor, $class);
18 4         10 $visitor->_init();
19 4         33 return $visitor;
20             }
21              
22             sub _init {
23 4     4   6 my ($self) = @_;
24 4         19 $self->{sort_function} = undef;
25 4         11 $self->SUPER::_init();
26             }
27              
28             # pre-built sort functions
29             sub SORT_FILES_FIRST {
30             return sub ($$$) {
31 162     162   280 my ($path, $left, $right) = @_;
32 162         676 $left = File::Spec->catdir($path, $left);
33 162         484 $right = File::Spec->catdir($path, $right);
34 162 100 100     3184 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 900 }
39              
40             sub SORT_DIRS_FIRST {
41             return sub ($$$) {
42 168     168   306 my ($path, $left, $right) = @_;
43 168         684 $left = File::Spec->catdir($path, $left);
44 168         524 $right = File::Spec->catdir($path, $right);
45 168 100 100     3226 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 894 }
50              
51             sub setSortStyle {
52 5     5 1 1466 my ($self, $sort_function) = @_;
53 5 100 100     43 (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 2389 my ($self, $tree) = @_;
60 9 100 100     71 (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       12 ($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         32 my $root_dir = $tree->getNodeValue();
66 4 100 66     117 (-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         10 $self->_recursiveLoad($tree, $root_dir);
70             }
71              
72             sub _recursiveLoad {
73 18     18   35 my ($self, $t, $path) = @_;
74             # get a node filter if we have one
75 18         49 my $filter = $self->getNodeFilter();
76              
77             # get the contents of the directory
78 18 50       529 opendir(DIR, $path) || die "IO Error : Could not open directory : $!";
79             # avoid the . and .. symbolic links
80             my @dir_contents = grep {
81 18 100       411 $_ ne File::Spec->curdir() && $_ ne File::Spec->updir()
  216         725  
82             } readdir(DIR);
83 18         38 close(DIR);
84              
85             # sort them if we need to with full paths
86             @dir_contents = sort {
87 330         748 $self->{sort_function}->($path, $a, $b)
88 18 100       54 } @dir_contents if $self->{sort_function};
89              
90             # now traverse ...
91 18         37 foreach my $item (@dir_contents) {
92             # filter based on the item name
93 180 50 100     12879 $filter->($item) || next if defined($filter);
94             # get the full path for checking
95             # the item type and recursion
96 141         1223 my $full_path = File::Spec->catdir($path, $item);
97 141 100       2781 if (-d $full_path) {
    50          
98 15         53 my $new_tree = $t->new($item);
99 15         432 $t->addChild($new_tree);
100 15         1248 $self->_recursiveLoad($new_tree, $full_path);
101             }
102             elsif (-f $full_path) {
103 126         460 $t->addChild($t->new($item));
104             }
105             }
106             }
107              
108             1;
109              
110             __END__