/[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.7 - (show annotations)
Tue Feb 11 10:34:19 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.6: +62 -20 lines
+ loaded module may now lack 'mixin::with' declaration
+ this gets us the possibility to load modules from any perl namespace
   + enabled this mechanism

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

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