File Coverage

blib/lib/App/Framework/Extension.pm
Criterion Covered Total %
statement 50 50 100.0
branch 2 2 100.0
condition 8 11 72.7
subroutine 8 8 100.0
pod 5 5 100.0
total 73 76 96.0


line stmt bran cond sub pod time code
1             package App::Framework::Extension ;
2              
3             =head1 NAME
4              
5             App::Framework::Extension - Application Extension
6              
7             =head1 SYNOPSIS
8              
9             use App::Framework::Extension ;
10              
11              
12             =head1 DESCRIPTION
13              
14             Provides the base object from which all Extensions must be derived. Is itself derived from L and overrides
15             whichever methods are necessary to modify the application behaviour.
16              
17              
18             =cut
19              
20 26     26   15957 use strict ;
  26         30  
  26         673  
21 26     26   84 use Carp ;
  26         29  
  26         2055  
22              
23             our $VERSION = "1.000" ;
24              
25             #============================================================================================
26             # USES
27             #============================================================================================
28 26     26   107 use App::Framework::Core ;
  26         35  
  26         13068  
29              
30             #============================================================================================
31             # OBJECT HIERARCHY
32             #============================================================================================
33             #our @ISA = qw(App::Framework::Core) ;
34             our @ISA ;
35              
36             #============================================================================================
37             # GLOBALS
38             #============================================================================================
39              
40             =head2 FIELDS
41              
42             The following fields should be defined either in the call to 'new()', as part of a 'set()' call, or called by their accessor method
43             (which is the same name as the field):
44              
45              
46             =over 4
47              
48              
49             =back
50              
51             =cut
52              
53              
54             my %FIELDS = (
55             'extension_heap' => {}, # Extension-specific heap
56             );
57              
58             #============================================================================================
59              
60             =head2 CONSTRUCTOR
61              
62             =over 4
63              
64             =cut
65              
66             #============================================================================================
67              
68             =item B< new([%args]) >
69              
70             Create a new Extension.
71              
72             The %args are specified as they would be in the B method.
73              
74             =cut
75              
76             sub new
77             {
78 26     26 1 113 my ($obj, %args) = @_ ;
79              
80 26   33     123 my $class = ref($obj) || $obj ;
81              
82             #print "App::Framework::Extension->new() class=$class\n" ;
83              
84             ## Inherit from specified list
85 26         124 my $this = App::Framework::Core->inherit($class, %args) ;
86              
87 26         263 $this->_dbg_prt(["Extension - $class ISA=@ISA\n"]) ;
88              
89             # Create object
90             # my $this = $class->SUPER::new(%args) ;
91              
92             #$this->debug(1) ;
93             #print "App::Framework::Extension->new() - END\n" ;
94            
95 26         188 return($this) ;
96             }
97              
98              
99              
100             #============================================================================================
101              
102             =back
103              
104             =head2 CLASS METHODS
105              
106             =over 4
107              
108             =cut
109              
110             #============================================================================================
111              
112             #-----------------------------------------------------------------------------
113              
114             =item B< init_class([%args]) >
115              
116             Initialises the object class variables.
117              
118             =cut
119              
120             sub init_class
121             {
122 26     26 1 54 my $class = shift ;
123 26         70 my (%args) = @_ ;
124              
125             # Add extra fields
126 26         194 $class->add_fields(\%FIELDS, \%args) ;
127              
128             # init class
129 26         178 $class->SUPER::init_class(%args) ;
130              
131             }
132              
133              
134             #============================================================================================
135              
136             =back
137              
138             =head2 OBJECT METHODS
139              
140             =over 4
141              
142             =cut
143              
144             #============================================================================================
145              
146             #----------------------------------------------------------------------------
147              
148             =item B
149              
150             Returns HEAP space for the calling module
151            
152             =cut
153              
154              
155             sub heap
156             {
157 230     230 1 190 my $this = shift ;
158 230         187 my ($level) = @_ ;
159              
160             ## Get calling package
161 230   50     336 $level ||= 0 ;
162 230         547 my $pkg = (caller($level))[0] ;
163              
164             #print "##!!## heap($pkg)\n" ;
165             #$this->dump_callstack() ;
166              
167             # Get total heap space
168 230         4081 my $heap = $this->extension_heap() ;
169              
170             # Return this package's area
171 230   100     390 $heap->{$pkg} ||= {} ;
172 230         865 $this->_dbg_prt(["#!# this=$this pkg=$pkg Heap [$heap->{$pkg}] Total heap [$heap]=", $heap]) ; ;
173              
174 230         324 return $heap->{$pkg} ;
175             }
176              
177              
178             # TODO: Specify fn(s) as method name strings that get called on this
179              
180             #----------------------------------------------------------------------------
181              
182             =item B
183              
184             Hi-jack the specified application function. %spec is a HASH of:
185              
186             key = function name
187             value = CODE ref to subroutine
188            
189             =cut
190              
191              
192             sub extend_fn
193             {
194 1     1 1 1 my $this = shift ;
195 1         3 my (%spec) = @_ ;
196              
197             #$this->debug(2);
198 1         4 my $pkg = (caller(0))[0] ;
199 1         8 $this->_dbg_prt(["#!# extend_fn() pkg=$pkg (this=$this)", \%spec]) ; ;
200            
201 1         15 my $heap = $this->heap(1) ;
202 1         8 $this->_dbg_prt(["#!# heap [$heap]", $heap]) ; ;
203 1         4 foreach my $fn (keys %spec)
204             {
205             # save original
206 3         50 $heap->{'extend_fn'}{$fn} = $this->$fn ;
207             {
208 3   100     4 my $saved = $heap->{'extend_fn'}{$fn} || "" ;
  3         10  
209 3         14 $this->_dbg_prt(["#!# + pkg=$pkg Extend $fn - saved ($saved), new $fn=($spec{$fn})\n"]) ;
210             }
211            
212             # update function
213 3         55 $this->$fn($spec{$fn}) ;
214            
215             }
216 1         5 $this->_dbg_prt(["#!# extend_fn() - END", "HEAP=", $heap]) ; ;
217              
218             }
219              
220             #----------------------------------------------------------------------------
221              
222             =item B
223              
224             Calls the function with specified args. If not extended by the extension then just calls the
225             default function.
226              
227             NOTE: Application function is always called with:
228              
229             fn($app, \%options, @args)
230            
231             =cut
232              
233              
234             sub call_extend_fn
235             {
236 229     229 1 186 my $this = shift ;
237 229         302 my ($fn, @args) = @_ ;
238              
239 229         305 my $heap = $this->heap(1) ;
240 229         243 my $call = $heap->{'extend_fn'}{$fn} ;
241             #$this->debug(2);
242 229         474 my $pkg = (caller(0))[0] ;
243 229   100     390 my $dbg_call = $call||'' ;
244 229         648 $this->_dbg_prt(["#!# pkg=$pkg call_extend_fn($fn) call=$dbg_call HEAP [$heap]=", $heap]) ; ;
245              
246             # do call if specified
247 229 100       372 if ($call)
248             {
249             # get options
250 223         481 my %options = $this->options() ;
251              
252 223         912 $this->_dbg_prt(["#!# + pkg=$pkg calling $fn call=$call\n"]) ;
253            
254             # do call
255 223         528 &$call($this, \%options, @args) ;
256            
257             }
258            
259             }
260              
261             # ============================================================================================
262             # END OF PACKAGE
263              
264             =back
265              
266             =head1 DIAGNOSTICS
267              
268             Setting the debug flag to level 1 prints out (to STDOUT) some debug messages, setting it to level 2 prints out more verbose messages.
269              
270             =head1 AUTHOR
271              
272             Steve Price C<< >>
273              
274             =head1 BUGS
275              
276             None that I know of!
277              
278             =cut
279              
280             1;
281              
282             __END__