/[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.9 - (hide annotations)
Tue Feb 18 18:35:30 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.8: +20 -1 lines
+ encapsulated/abstracted some more functionality: sub load_single

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

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