/[cvs]/nfo/perl/libs/DesignPattern/Bridge.pm
ViewVC logotype

Contents of /nfo/perl/libs/DesignPattern/Bridge.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations)
Fri Feb 21 08:38:21 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.10: +19 -3 lines
+ additional checks
+ raising exceptions

1 ## --------------------------------------------------------------------------------
2 ## $Id: Bridge.pm,v 1.10 2003/02/20 20:50:32 joko Exp $
3 ## --------------------------------------------------------------------------------
4 ## $Log: Bridge.pm,v $
5 ## Revision 1.10 2003/02/20 20:50:32 joko
6 ## + small exception handling: now inheriting from little Exception object
7 ##
8 ## Revision 1.9 2003/02/18 18:35:30 joko
9 ## + encapsulated/abstracted some more functionality: sub load_single
10 ##
11 ## Revision 1.8 2003/02/14 14:20:05 joko
12 ## + modified mixin behaviour
13 ##
14 ## Revision 1.7 2003/02/11 10:34:19 joko
15 ## + loaded module may now lack 'mixin::with' declaration
16 ## + this gets us the possibility to load modules from any perl namespace
17 ## + enabled this mechanism
18 ##
19 ## Revision 1.6 2003/02/09 16:22:51 joko
20 ## + pseudo constructor mechanism via options
21 ##
22 ## Revision 1.5 2003/01/31 01:19:50 root
23 ## + fixed: doesn't need Log::Dispatch any more, but uses it if available
24 ##
25 ## Revision 1.4 2003/01/20 16:55:15 joko
26 ## + sub mixinPackage
27 ## + sub include
28 ##
29 ## Revision 1.3 2002/12/16 19:57:12 joko
30 ## + sub unload
31 ##
32 ## Revision 1.2 2002/12/15 02:06:15 joko
33 ## + feature to be able to specify module in non-perl-style when loading plugins: e.g. $process->load('Setup/Storage')
34 ##
35 ## Revision 1.1 2002/12/13 21:46:29 joko
36 ## + initial check-in
37 ##
38 ## --------------------------------------------------------------------------------
39
40
41 package DesignPattern::Bridge;
42
43 use strict;
44 use warnings;
45
46 use base qw(
47 DesignPattern::Object
48 DesignPattern::Exception
49 );
50
51
52 use Data::Dumper;
53
54 ## ======== object inheritance ========
55
56 # TODO / REFACTORING PROPOSAL
57 # leading from Data::Storage to code abstracted out into this module - DesignPattern::Bridge
58 # - this is no inheritance and it doesn't have to be
59 # - implement this module as a bridge to its sub-modules
60 # - use the BridgePattern (http://c2.com/cgi/wiki?BridgePattern)
61 # Using patterns was already successfully done with Data::Storage::Handler
62 # by implementing the AdapterPattern (http://c2.com/cgi/wiki?AdapterPattern)
63 # with Perl's AUTOLOAD-mechanism
64 # - try to use Perl's "tie" command to implement this functionality here instead of using AUTOLOAD!
65 # - sub getChildNodes
66 # - sub run
67
68 # 2003-02-11, joko: does this have anything in parallel with CPAN's Class::Inner?
69
70
71 # get logger instance
72 my $logger = eval { Log::Dispatch::Config->instance; };
73
74 my $meta;
75
76 ## ======== object constructor ========
77 sub new {
78 my $invocant = shift;
79 my $class = ref($invocant) || $invocant;
80 my @args = ();
81 @_ && (@args = @_);
82 $logger->debug( __PACKAGE__ . "->new(@args)" ) if $logger;
83 my $self = { @_ };
84
85 # trace
86 #print "class: $class", "\n";
87
88 # create instance
89 bless $self, $class;
90
91 return $self;
92 }
93
94
95 ## ======== method overrider ========
96 sub AUTOLOAD2 {
97
98 my $self = shift;
99 our $AUTOLOAD;
100
101 ##print "AUTOLOAD\n";
102
103 my $method = $AUTOLOAD;
104 $method =~ s/^.*:://;
105
106 $logger->debug( __PACKAGE__ . "->" . $method . "(@_)" . " (AUTOLOAD called, not dispatched)" ) if $logger;
107
108 ## ->DESTROY would - if not declared - trigger an AUTOLOAD also
109 return if $method =~ m/::DESTROY$/;
110
111 ## if ($self->_filter_AUTOLOAD($method)) {
112 ## $self->_accessStorage();
113 ## $self->{STORAGEHANDLE}->$method(@_);
114 ## }
115
116 }
117
118 sub _getPluginPackage {
119 my $self = shift;
120 my $modulename_load = shift;
121
122 # substitute slashes through double double-colons to load modules perl-style
123 $modulename_load =~ s/\//::/g;
124
125 # build full package name
126 my $self_classname = ref $self;
127 # name
128 my $package = $modulename_load;
129
130 # if package is absolute, cut away prefix ('/' or '::')
131 if ($package !~ s/^:://) {
132 # else: prefix with base classname if above name is relative (lacks of '/' or '::')
133 $package = $self_classname . '::' . $package
134 }
135
136 return $package;
137 }
138
139 sub load {
140
141 my $self = shift;
142 my $modulename = shift;
143 my $options = shift;
144
145 if (ref $modulename eq 'ARRAY') {
146 foreach (@$modulename) {
147 $self->load_single($_, $options);
148 }
149 } else {
150 $self->load_single($modulename, $options);
151 }
152
153 }
154
155 sub load_single {
156
157 my $self = shift;
158 my $modulename_load = shift;
159
160 my $options = shift;
161
162 my $self_modulename = ref $self;
163 my $package = $self->_getPluginPackage($modulename_load);
164
165 if ($meta->{loaded}->{$package}) {
166 return 1;
167 }
168
169 #$logger->info( __PACKAGE__ . "->load: $package" ) if $logger;
170 #$logger->info( __PACKAGE__ . "->load: $self_modulename" ) if $logger;
171 $logger->debug( $self_modulename . "->load: $package\t[via " . __PACKAGE__ . "]" ) if $logger;
172
173 # this is the module testing phase - use mixin doesn't seem to propagate errors by default
174 eval("use $package;");
175 $self->checkExceptions();
176
177 =pod
178 if ($@) {
179 $meta->{loaded}->{$package} = 0;
180 # include caller information
181 my @caller = caller;
182 my $caller_msg = $caller[1] . ':' . $caller[2];
183 my $msg = __PACKAGE__ . "->load: $@ ($caller_msg)";
184 if ($logger) {
185 $logger->error($msg);
186 } else {
187 print $msg, "\n";
188 }
189 }
190 =cut
191
192 #print "ref-1: ", ref $self, "\n";
193 #print "ref-2: ", ref $self::SUPER, "\n";
194
195 # V1:
196 #bless $self, $package;
197
198 # V2:
199 $self->mixinPackage($package);
200
201 if (my $method = $options->{method}) {
202 $self->$method();
203 }
204
205 return 1;
206
207 }
208
209 sub mixinPackage {
210 my $self = shift;
211 my $package = shift;
212
213 # switch into foreign package and prepare for mixin
214 $self->mixin_prepare($package);
215
216 # switch into local package (scope which uses DesignPattern::Bridge) and mixin plugin-module
217 $self->mixin_do($package);
218
219 }
220
221 # TODO: maybe refactor to DesignPattern::Object? what about the '$logger'?
222 sub mixin_prepare {
223 my $self = shift;
224 my $package = shift;
225 my $self_classname = ref $self;
226 eval("package $package; use mixin::with '$self_classname';");
227
228 # FIXME: --- this is redundant ---
229 if ($@) {
230 $meta->{loaded}->{$package} = 0;
231 $logger->error( __PACKAGE__ . "->load: $@" ) if $logger;
232 } else {
233 $meta->{loaded}->{$package} = 1;
234 }
235 # FIXME: --- this is redundant ---
236
237 }
238
239 sub mixin_do {
240 my $self = shift;
241 my $package = shift;
242 # switch into foreign package and mixin plugin-module
243 my $self_classname = ref $self;
244 eval("package $self_classname; use mixin '$package';");
245 #eval("use mixin_all '$package';");
246
247 # FIXME: --- this is redundant ---
248 if ($@) {
249 $meta->{loaded}->{$package} = 0;
250 $logger->error( __PACKAGE__ . "->load: $@" ) if $logger;
251 } else {
252 $meta->{loaded}->{$package} = 1;
253 }
254 # FIXME: --- this is redundant ---
255
256 }
257
258 sub unload {
259
260 my $self = shift;
261 my $modulename_unload = shift;
262
263 my $package = $self->_getPluginPackage($modulename_unload);
264
265 if ($meta->{loaded}->{$package}) {
266 $meta->{loaded}->{$package} = 0;
267 my $where = __PACKAGE__ . ':' . __LINE__;
268 $logger->debug( __PACKAGE__ . "->unload: FIXME: DESTROY object is not implemented at '$where'." ) if $logger;
269 }
270
271 }
272
273
274 sub boot {
275 my $self = shift;
276 $self->_abstract_function('boot');
277 }
278
279 sub include {
280 my $self = shift;
281 my $includefile = shift;
282 my $package = shift;
283
284 # pre-flight checks
285 if (!$includefile) {
286 $self->raiseException('Filename for inclusion was empty.');
287 return;
288 }
289
290 # go for it ...
291 eval("require '$includefile';");
292 # ... and handle errors afterwards catching every message from perl itself ...
293 return if $self->checkExceptions();
294
295 # ... otherwise continue assuming everything is fine
296 $self->mixinPackage($package) if $package;
297
298 }
299
300 1;
301 __END__

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed