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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations)
Thu Feb 20 20:50:32 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.9: +12 -2 lines
+ small exception handling: now inheriting from little Exception object

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

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