File Coverage

lib/Grid/Request/Param.pm
Criterion Covered Total %
statement 9 90 10.0
branch 0 36 0.0
condition 0 9 0.0
subroutine 3 12 25.0
pod 4 6 66.6
total 16 153 10.4


line stmt bran cond sub pod time code
1             package Grid::Request::Param;
2              
3             =head1 NAME
4              
5             Param.pm - Models a parameter for Grid::Request jobs.
6              
7             =head1 VERSION
8              
9             This document refers to Param.pm
10              
11             =head1 SYNOPSIS
12              
13             use Grid::Request::Param;
14             my $param = Grid::Request:Param->new();
15             $param->type("DIR");
16             $param->key('--file=$(Name)');
17             $param->value("/path/to/some/directory");
18              
19             =head1 DESCRIPTION
20              
21             A module that models Grid::Request parameters.
22              
23             =over 4
24              
25             =cut
26              
27 2     2   92307 use strict;
  2         4  
  2         77  
28 2     2   1260 use Log::Log4perl qw(get_logger);
  2         55256  
  2         19  
29 2     2   1367 use Grid::Request::Exceptions;
  2         6  
  2         2455  
30              
31             my $MW_PARAM_DELIMITER = ":";
32              
33             my %VALID_TYPE = ( ARRAY => 1,
34             DIR => 1,
35             PARAM => 1,
36             FILE => 1,
37             );
38              
39             my $logger = get_logger(__PACKAGE__);
40              
41             our $VERSION = '0.11';
42             if ($^W) {
43             $VERSION = $VERSION;
44             }
45              
46             # This is the constructor
47             sub new {
48 0     0 0   my ($class, @args) = @_;
49 0   0       my $self = bless {}, $class || ref($class);
50 0           $self->_init(@args);
51 0           return $self;
52             }
53              
54             # This _init() method is used to initialize new instances of this class/module.
55             sub _init {
56 0     0     my ($self, @args) = @_;
57 0 0 0       if (scalar @args == 1 && ref(\$args[0]) eq "SCALAR") {
58 0           my $param_string = $args[0];
59 0           my @parts = split(/$MW_PARAM_DELIMITER/, $param_string);
60 0 0 0       if (scalar @parts == 3) {
    0          
61 0           $self->{_type} = $parts[0];
62 0           $self->{_value} = $parts[1];
63 0           $self->{_key} = $parts[2];
64             } elsif (scalar @parts == 2 && $parts[0] eq "PARAM") {
65 0           $self->{_type} = $parts[0];
66 0           $self->{_value} = $parts[1];
67             }
68             } else {
69 0           $self->{_type} = "PARAM";
70 0           $self->{_value} = undef;
71 0           $self->{_key} = undef;
72             }
73             }
74              
75              
76             =item $obj->type([$type]);
77            
78             B Sets or retrieves the type of the parameter. Allowable "types"
79             are: ARRAY, DIR, FILE, and the default, PARAM.
80              
81             B An optional scalar, $type.
82              
83             B If called as a getter (no-arguments), returns the current type.
84             If called as a setter, nothing is returned (undef).
85              
86             =cut
87              
88             sub type {
89 0     0 1   $logger->debug("In type.");
90 0           my ($self, @args) = @_;
91 0 0         if (@args) {
92 0           my $type = $args[0];
93 0 0         if ($VALID_TYPE{$type}) {
94 0           $self->{_type} = $args[0];
95             } else {
96 0           Grid::Request::Exception->throw("Invalid param type: $type.");
97             }
98             } else {
99 0           return $self->{_type};
100             }
101             }
102              
103              
104             =item $obj->value([$value]);
105              
106             B A getter/setter that is used to set and retrieve the "value" of
107             a Grid::Request parameter. Grid::Request jobs may specified an executable to run
108             on the grid, and the executable may have or require one or more arguments (such as
109             those typically specified on the command line). These arguments are modeled with
110             the Grid::Request::Param module. Simple parameters do not trigger any iteration,
111             however, parameters of type "ARRAY", "DIR", and "FILE", trigger iterations, and
112             subsequently grid jobs that perform "parameter sweep" (sometimes referred to as
113             "array jobs").
114              
115             B None.
116              
117             B If called as a getter (no-arguments), returns the current value
118             of the parameter. If called as a setter, nothing is returned (undef).
119              
120             =cut
121              
122             sub value {
123 0     0 1   $logger->debug("In value.");
124 0           my ($self, @args) = @_;
125 0 0         if (@args) {
126 0           $self->{_value} = $args[0];
127             } else {
128 0           return $self->{_value};
129             }
130             }
131              
132              
133             =item $obj->key([$key]);
134              
135             B For each parameter, the key is what tells how the parameter
136             should be passed as a command line argument and how the values from the iterable
137             directory, array or file are to be dropped into the argument. Parameter keys can
138             make use of two tokens: $(Index) and $(Name). The $(Index) token is replaced at
139             with the actual sequence number of the job on the grid, and the $(Name) token
140             is replaced with the string taken from the iterable value. In the case of parameters
141             of type
142              
143             FILE -> $(Name) is replaced with the string from the line in the file
144             ARRAY -> $(Name) is replaced with the value of the element of the array
145             DIR -> $(Name) is replaced with the name of the file in the directory
146              
147             Examples:
148              
149             FILE
150             # From the constructor
151             Grid::Request::Param->new( type => "FILE",
152             key => '--string=$(Name)',
153             value => "/path/to/some/file.txt" )
154              
155             DIR
156             $param = Grid::Request::Param->new();
157             $param->type("DIR");
158             $param->key('--filepath=$(Name)');
159             $param->value("/path/to/some/directory");
160              
161             ARRAY
162             $param = Grid::Request::Param->new();
163             $param->type("ARRAY");
164             $param->key('--element=$(Name)');
165             $param->value(\@array);
166              
167             B None.
168              
169             B A non-negative integer scalar.
170              
171             =cut
172              
173             sub key {
174 0     0 1   my ($self, @args) = @_;
175 0           $logger->debug("In key.");
176 0 0         if (@args) {
177 0           $self->{_key} = $args[0];
178             } else {
179 0           return $self->{_key};
180             }
181             }
182              
183             =item $obj->count();
184              
185             B Retrieves the number of iterations that this parameter will
186             trigger. For parameters of type "ARRAY", it will be the nubmer of array
187             elements, for parameters of type "DIR", it will be the number of non-hidden
188             files in the specified directory; for parameters of type "FILE", it will the
189             number of lines in the file (with the exception of lines with nothing but
190             whitespace).
191              
192             B None.
193              
194             B A non-negative integer scalar.
195              
196             =cut
197              
198             sub count {
199 0     0 1   my ($self, @args) = @_;
200 0           $logger->debug("In count.");
201 0           my $count;
202 0           my $type = $self->type();
203 0 0         if ($type eq "PARAM") {
    0          
    0          
    0          
204 0           $count = 1;
205             } elsif ($type eq "DIR") {
206 0           my $dir = $self->value();
207 0           $count = _dir_count($dir);
208             } elsif ($type eq "FILE") {
209 0           my $file = $self->value();
210 0           $count = _file_count($file);
211             } elsif ($type eq "ARRAY") {
212 0           my $array_ref = $self->value();
213 0           $count = scalar(@$array_ref);
214             } else {
215 0           Grid::Request::InvalidArgumentException->throw("Unknown parameter type: $type.");
216             }
217 0           $logger->debug("Returning: $count.");
218 0           return $count;
219             }
220              
221             # A private method used to count how many files are in a directory.
222             # Hidden files are NOT included.
223             sub _dir_count {
224 0     0     $logger->debug("In _dir_count.");
225 0           my $dir = shift;
226 0 0         if (! -d $dir) {
227 0           Grid::Request::InvalidArgumentException->throw("$dir is not a directory.");
228             }
229              
230             # Go through all the files
231 0 0         opendir(DIR, $dir) or
232             Grid::Request::Exception->throw("Could not open directory $dir.");
233              
234             # Make sure we ignore hidden files/paths here. That's what the grep is for.
235 0           my @files = grep { !/^\./ } readdir DIR;
  0            
236 0           closedir DIR;
237              
238 0           my $count = scalar(@files);
239 0           $logger->debug("Returning $count.");
240 0           return $count;
241             }
242              
243              
244             # A private method used to count how many lines are in a file. Newlines
245             # are considered to be the separator. In addition, if the line only contains
246             # whitespace, then it is NOT counted...
247             sub _file_count {
248 0     0     $logger->debug("In _file_count.");
249 0           my $file = shift;
250 0 0         if (! -f $file) {
251 0           Grid::Request::InvalidArgumentException->throw("$file is not a file.");
252             }
253             # Open the file for reading.
254 0 0         open (FILE, "<", $file) or
255             Grid::Request::Exception->throw("Could not open file $file.");
256 0           my $count = 0;
257             # Iterate over the file and examine each line.
258 0           while () {
259 0           my $line = $_;
260 0 0         if ($line =~ m/\W/) {
261 0           $count++;
262             } else {
263 0           $logger->debug("Didn't count line containing just white space.");
264             }
265             }
266             # Attempt to close the filhandle.
267 0 0         close FILE or
268             Grid::Request::Exception->throw("Could not close filehandle for: $file.");
269 0           $logger->debug("Returning $count.");
270 0           return $count;
271             }
272              
273             sub to_string {
274 0     0 0   my $self = shift;
275 0           my $string;
276 0 0         if ($self->type() eq "PARAM") {
277 0           $string = sprintf( '%s' . $MW_PARAM_DELIMITER . '%s',
278             $self->type(), $self->value());
279             } else {
280 0           $string = sprintf( '%s' . $MW_PARAM_DELIMITER . '%s' . $MW_PARAM_DELIMITER . '%s',
281             $self->type(), $self->value(), $self->key() );
282             }
283 0           return $string;
284             }
285              
286             1;
287              
288             __END__