/[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.8 - (hide annotations)
Fri Feb 14 14:20:05 2003 UTC (21 years, 8 months ago) by joko
Branch: MAIN
Changes since 1.7: +19 -7 lines
+ modified mixin behaviour

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

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