File Coverage

blib/lib/OOP/_getArgs.pm
Criterion Covered Total %
statement 163 174 93.6
branch 87 108 80.5
condition 70 123 56.9
subroutine 12 13 92.3
pod n/a
total 332 418 79.4


line stmt bran cond sub pod time code
1             package OOP::_getArgs;
2              
3 1     1   6 use strict;
  1         2  
  1         40  
4 1     1   5 use Carp;
  1         2  
  1         6514  
5              
6             sub EXISTS {
7              
8 0     0   0 my ($self,$key) = @_;
9              
10 0         0 my $value = $self->{ARGS};
11            
12 0         0 return (exists $value->{$key});
13              
14             }
15             sub TIEHASH {
16              
17 63     63   100 my ($class, $ARGS) = @_;
18              
19 63         111 $ARGS->{_INDEX} = {};
20            
21 63   33     165 my $arguments = $ARGS->{ARGS} || croak "No arguments were passed to the prototype!";
22 63   33     147 my $prototype = $ARGS->{PROTOTYPE} || croak "No prototype was passed to the prototype!";
23              
24 63         65 my $self = $ARGS;
25              
26 63         227 return bless $self, $class;
27            
28             }
29             sub STORE {
30              
31 21     21   59 my ($self, $key, $val) = @_;
32              
33 21         32 my $value = $self->{ARGS};
34 21         27 my $myProto = $self->{PROTOTYPE};
35              
36 21   66     52 my $_mainobj = $self->{_MAIN} || $self;
37              
38 21         48 my $_parent = $_mainobj->{_INDEX}->{$value}->{parent};
39 21         47 my $_parentkey = $_mainobj->{_INDEX}->{$value}->{parentkey};
40 21         34 my $_parentPrototype = $_parent->{proto}->{$_parentkey};
41              
42 21         22 my $_currPrototype;
43              
44 21 100 100     234 if (exists($value->{$key}) &&
    100 100        
      100        
      100        
      100        
45             exists($myProto->{$key}) &&
46             ref $myProto->{$key} eq 'HASH' &&
47             ref $_parentPrototype eq 'HASH' &&
48             !exists($myProto->{$key}->{dataType})
49             )
50             {
51 2         5 $_currPrototype = $_parentPrototype;
52             }
53             elsif ((ref $myProto->{$key} eq 'HASH') && exists($myProto->{$key}->{dataType}))
54             {
55 8         13 $_currPrototype = $myProto->{$key};
56             }
57             else
58             {
59 11         20 my $protoVal = $myProto->{$key};
60 11 100 100     56 my $dataType = exists($myProto->{$key}) ? ($myProto->{$key} ne '' ? ref($myProto->{$key}) : 'scalar') : (ref $val || 'scalar');
    100          
61 11 50 33     109 if ((ref $myProto->{$key} eq 'ARRAY') && (scalar @{$myProto->{$key}} == 0))
  0 100 66     0  
    100 66        
62 1         4 {
63 0         0 $protoVal = '';
64             }
65             elsif((ref $myProto->{$key} eq 'HASH') && (scalar %{$myProto->{$key}} == 0))
66             {
67 1         3 $protoVal = '';
68             }
69             elsif ((ref $myProto->{$key} eq '') && (scalar $myProto->{$key} <= 0))
70             {
71 9         16 $protoVal = '';
72             }
73 11         24 $_currPrototype->{dataType} = $dataType;
74 11 100       30 $_currPrototype->{writeAccess} = $protoVal eq '' ? 1 : 0;
75 11         15 $_currPrototype->{readAccess} = 1;
76 11 100       26 $_currPrototype->{allowEmpty} = $protoVal ne '' ? 1 : 0;
77 11         15 $_currPrototype->{locked} = 0;
78 11         16 $_currPrototype->{required} = 1;
79 11 100       25 $_currPrototype->{minLength} = $_currPrototype->{maxLength} = length($protoVal) if $protoVal ne '' ;
80 11         25 $_currPrototype->{value} = $myProto->{$key};
81             }
82            
83 21 100       46 if (uc($_currPrototype->{dataType}) eq 'HASH')
84             {
85 5 50 0     28 ! (exists($_currPrototype->{writeAccess}) && ($_currPrototype->{writeAccess} <= 0)) ||
      33        
86             ( exists($value->{$key}) || croak "'$key' is an invalid key according to constructor!" );
87              
88 5 100       431 ref $val eq 'HASH' || croak "Attempt to pass improper data type to '$key'!";
89             }
90             else
91             {
92 16 100 66     286 !(exists($_currPrototype->{writeAccess}) &&
93             ($_currPrototype->{writeAccess} == 0)) ||
94             croak "'$key' is read-only according to constructor!";
95              
96 14 50 33     84 !(exists($_currPrototype->{writeAccess}) &&
      33        
97             ($_currPrototype->{writeAccess} == -1) &&
98             (exists($value->{$key}))) ||
99             croak "'$key' is read-only according to constructor!";
100            
101 14   100     46 my $valType = ref($val) || 'scalar';
102 14         17 $valType = uc($valType);
103            
104 14 100       338 uc($_currPrototype->{dataType}) eq $valType || croak "Attempt to pass improper data type to '$key'!";
105             }
106              
107 12         76 $self->_checkArgs({
108             key => $key,
109             action => 'store',
110             value => $val,
111             argsRef => $value,
112             hashRef => $myProto
113             });
114              
115 8         53 $value->{$key} = $val;
116            
117             }
118             sub DELETE {
119              
120 4     4   8 my ($self, $key) = @_;
121              
122 4         5 my $value = $self->{ARGS};
123            
124 4 100       16 return unless exists $value->{$key};
125            
126 3         5 my $myProto = $self->{PROTOTYPE};
127 3         5 my $_currPrototype = $myProto->{$key};
128            
129 3 100 66     237 ref $_currPrototype eq 'HASH' && exists($_currPrototype->{locked}) && ($_currPrototype->{locked} == 1) ?
130             croak "'$key' may not be removed according to constructor!" :
131             delete $value->{$key};
132            
133             }
134              
135             sub CLEAR {
136              
137 1     1   102 my $self = shift;
138              
139 1   33     8 my $_mainobj = $self->{_MAIN} || $self;
140              
141 1         2 $self->{ARGS}->{$_} = undef foreach keys %{$self->{ARGS}};
  1         11  
142            
143             }
144             sub FETCH {
145              
146 65     65   1349 my ($self, $key) = @_;
147              
148 65   66     221 my $_mainobj = $self->{_MAIN} || $self;
149 65         85 my $_parent = $self->{PARENT};
150 65         90 my $_parentkey = $self->{PARENTKEY};
151 65         83 my $value = $self->{ARGS};
152 65         79 my $myProto = $self->{PROTOTYPE};
153              
154 65         292 $self->_checkArgs({
155             key => $key,
156             action => 'fetch',
157             argsRef => $value,
158             hashRef => $myProto
159             });
160              
161 63 50       244 if (ref $myProto eq 'HASH')
162             {
163 63 100 66     490 my $protoType = ((ref $myProto->{$key} eq 'HASH') &&
164             (exists($myProto->{$key}->{dataType})) &&
165             (uc($myProto->{$key}->{dataType}) eq 'HASH')) ?
166             $myProto->{$key}->{value}:
167             $myProto->{$key};
168              
169 63         259 $_mainobj->{_INDEX}->{$value} = {
170             parent => $_parent,
171             parentkey => $_parentkey
172             };
173            
174 63 100       222 if (ref($value->{$key}) eq 'HASH')
175             {
176 59         438 my $obj = tie(my %test, 'OOP::_getArgs', {
177             _MAIN => $_mainobj,
178             PARENT => {
179             args => $value,
180             proto => $myProto
181             },
182             PARENTKEY => $key,
183             ARGS => $value->{$key},
184             PROTOTYPE => $protoType
185             });
186            
187 59         363 return (\%test);
188             }
189             }
190            
191 4         17 return $value->{$key};
192              
193             }
194              
195             sub FIRSTKEY {
196              
197 2     2   4 my ($self) = @_;
198              
199 2         3 my $temp = keys %{$self->{ARGS}};
  2         5  
200              
201 2         16 return scalar each %{$self->{ARGS}};
  2         13  
202            
203             }
204              
205             sub NEXTKEY {
206            
207 2     2   3 my ($self) = @_;
208            
209 2         549 return each %{$self->{ARGS}};
  2         12  
210              
211             }
212              
213             sub _checkArgs {
214              
215 77     77   112 my ($self, $ARGS) = @_;
216              
217 77         104 my $action = $ARGS->{action};
218 77         109 my $accessKey = $ARGS->{key};
219 77         89 my $storeVal = $ARGS->{value};
220 77         88 my $argsRef = $ARGS->{argsRef};
221 77         100 my $hashRef = $ARGS->{hashRef};
222              
223 77 100       151 if (exists($hashRef->{$accessKey}))
224             {
225 69         101 my $value = $hashRef->{$accessKey};
226              
227 69         141 $ARGS->{_prototype} = $value;
228 69         137 $self->_checkParameter($ARGS);
229             }
230             else
231             {
232 8   33     21 my $_mainobj = $self->{_MAIN} || $self;
233            
234 8   66     37 my $_parent = $_mainobj->{_INDEX}->{$argsRef}->{parent} || $self->{PARENT};
235 8   66     27 my $_parentkey = $_mainobj->{_INDEX}->{$argsRef}->{parentkey} || $self->{PARENTKEY};
236 8         13 my $_parentPrototype = $_parent->{proto}->{$_parentkey};
237              
238 8         13 $ARGS->{_prototype} = $_parentPrototype;
239 8         16 $self->_checkParameter($ARGS);
240             }
241            
242 71         164 return ();
243            
244             }
245             sub _checkParameter {
246              
247 77     77   91 my ($self, $ARGS) = @_;
248              
249 77         98 my $action = $ARGS->{action};
250 77         97 my $accessKey = $ARGS->{key};
251 77         94 my $storeVal = $ARGS->{value};
252 77         91 my $argsRef = $ARGS->{argsRef};
253 77         85 my $hashRef = $ARGS->{hashRef};
254 77         88 my $_prototype = $ARGS->{_prototype};
255              
256 77 100 100     357 if ((ref($_prototype) eq 'HASH') && exists($_prototype->{dataType}))
257             {
258 40         199 $self->_checkAttributes({
259             action => $action,
260             value => $storeVal,
261             attributes => $_prototype,
262             key => $accessKey,
263             argsRef => $argsRef
264             });
265             }
266             else
267             {
268 37 100 66     395 if ((!exists($argsRef->{$accessKey})) && exists($hashRef->{$accessKey}))
    50 33        
    50 33        
269             {
270 1 50       5 if (uc($action) ne 'STORE')
271             {
272 0         0 croak "Parameter '$accessKey' was not passed to the constructor!";
273             }
274             }
275             elsif (exists($argsRef->{$accessKey}) && (!exists($hashRef->{$accessKey})))
276             {
277 0         0 croak "Parameter '$accessKey' is not permitted!";
278             }
279             elsif (!exists($argsRef->{$accessKey}) && (!exists($hashRef->{$accessKey})))
280             {
281 0 0 0     0 if (((uc($action) ne 'STORE') && (uc($_prototype->{dataType}) eq 'HASH')) ||
      0        
282             (uc($_prototype->{dataType}) ne 'HASH')
283             )
284             {
285 0         0 croak "Parameter '$accessKey' is not a defined key!";
286             }
287             }
288             }
289              
290             }
291             sub _checkAttributes {
292              
293 40     40   54 my ($self, $ARGS) = @_;
294            
295 40         53 my $attribute = $ARGS->{attributes}; # prototype
296 40         54 my $argsRef = $ARGS->{argsRef};
297 40         64 my $action = uc($ARGS->{action});
298 40         49 my $storeVal = $ARGS->{value};
299 40         49 my $key = $ARGS->{key};
300 40         44 my $_countUp = 0;
301              
302 40   33     93 my $_mainobj = $self->{_MAIN} || $self;
303            
304 40   66     134 my $_parent = $_mainobj->{_INDEX}->{$argsRef}->{parent} || $self->{PARENT};
305 40   66     132 my $_parentkey = $_mainobj->{_INDEX}->{$argsRef}->{parentkey} || $self->{PARENTKEY};
306             # my $_parent = $_mainobj->{_INDEX}->{$argsRef}->{parent};
307             # my $_parentkey = $_mainobj->{_INDEX}->{$argsRef}->{parentkey};
308 40         65 my $_parentArgs = $_parent->{args}->{$_parentkey};
309 40         54 my $_parentPrototype = $_parent->{proto}->{$_parentkey};
310              
311 40         39 my ($verbIs, $verbAre);
312            
313 40         73 for (qw( allowEmpty dataType maxLength minLength readAccess required value writeAccess ))
314             {
315 320 50       707 exists $attribute->{$_} || croak "'$key' is missing the $_ attribute!";
316             }
317              
318 40 100       116 my $_isChild = ($_parentPrototype eq $attribute) ? 1 : 0;
319            
320 40 100 66     214 my $xvalue = (uc($action) eq 'STORE') || (uc($action) eq 'FETCH' && $_isChild ) ? $argsRef : $argsRef->{$key} ;
321              
322 40 100       97 if (ref($attribute->{value}) eq 'HASH')
323             {
324 36         42 for (keys(%{$attribute->{value}}))
  36         108  
325             {
326 72         162 my($_key, $_value) = ($_, $attribute->{value}->{$_});
327            
328 72 100 100     430 if ((ref $_value eq 'HASH') && ($_value->{required}) && (!exists $xvalue->{$_key}))
      100        
329             {
330 1         124 croak "The required key '$_key' was not passed to the constructor!";
331             }
332             }
333             }
334              
335 39         82 my $value = $argsRef->{$key};
336              
337 39 100       74 if ($action eq 'STORE')
338             {
339 10         15 $verbIs = $verbAre = 'would be';
340 10         13 $_countUp = 1;
341            
342 10 100       41 if ($attribute->{writeAccess} <= 0)
343             {
344 1 50       5 $key = $_isChild ? $_parentkey : $key;
345 1         142 croak "The '$key' structure is write protected!";
346             }
347             }
348             else
349             {
350 29         36 $verbIs = 'is';
351 29         34 $verbAre = 'are';
352             }
353            
354 38         250 (my $str = (caller(4))[3]) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;
  228         764  
355 38 100       166 if (uc($attribute->{dataType}) eq 'SCALAR')
    50          
356             {
357 4 100 50     196 $attribute->{readAccess} <= 0 and $str =~ /4f4f503a3a4163636573736f723a3a67657450726f7065727479/ ||
358             croak "Direct read access to '$key' is prohibited!";
359            
360 3 50       9 !(uc($action) eq 'STORE') or $value = $storeVal;
361            
362 3 50 33     10 !(($attribute->{allowEmpty} <= 0) && ($value eq '')) ||
363             croak "'$key' $verbIs empty in violation of constructor's definition!";
364            
365 3 100 66     22 if ((length($value) >= $attribute->{maxLength}))
    100 33        
366             {
367 1         141 croak "'$key' $verbIs too long, in violation of constructor's definition!";
368             }
369             elsif ((length($value) <= $attribute->{minLength}) && (($value ne '') && ($attribute->{allowEmpty} > 0)))
370             {
371 1         165 croak "'$key' $verbIs shorter in violation of constructor's definition!";
372             }
373             }
374             elsif (uc($attribute->{dataType}) eq 'HASH')
375             {
376 34 100       65 if ($_isChild)
377             {
378 7         10 $value = $_parentArgs;
379              
380 7 100       21 if (uc($action) eq 'FETCH')
    50          
381             {
382 1 50       5 exists($value->{$key}) || croak "The key '$key' does not exist and thus cannot be read!";
383             }
384             elsif(uc($action) eq 'STORE')
385             {
386 6 100       15 !exists($value->{$key}) || ($_countUp = 0);
387             }
388             }
389              
390 34 100       76 if (uc($action) eq 'STORE')
391             {
392 6         7 $key = $_parentkey;
393 6         7 $value = $_parentArgs;
394             }
395             else
396             {
397 28 50 0     64 $attribute->{readAccess} <= 0 and $str =~ /4f4f503a3a4163636573736f723a3a67657450726f7065727479/ ||
398             croak "Direct read access to '$key' is prohibited!";
399             }
400            
401 34         33 my $keys = keys(%{$value}) + $_countUp;
  34         72  
402            
403 34 50       81 if ($attribute->{allowEmpty} <= 0)
404             {
405 0 0       0 !($keys <= 0) || croak "'$key' $verbIs empty in violation of constructor's definition!";
406             }
407            
408 34 100       118 if (($keys > $attribute->{maxLength}))
    50          
409             {
410 1         235 croak "There $verbAre more items in '$key' structure than permitted!";
411             }
412             elsif (($keys < $attribute->{minLength}))
413             {
414 0         0 croak "There $verbAre fewer items in '$key' structure than permitted!";
415             }
416            
417             }
418            
419            
420 34         141 return();
421            
422             }
423              
424             1;
425