File Coverage

blib/lib/Flash/FLAP/App/Executive.pm
Criterion Covered Total %
statement 6 81 7.4
branch 0 28 0.0
condition 0 9 0.0
subroutine 2 12 16.6
pod 3 10 30.0
total 11 140 7.8


line stmt bran cond sub pod time code
1             package Flash::FLAP::App::Executive;
2             # Copyright (c) 2003 by Vsevolod (Simon) Ilyushchenko. All rights reserved.
3             # This program is free software; you can redistribute it and/or modify it
4             # under the same terms as Perl itself.
5             # The code is based on the -PHP project (http:#amfphp.sourceforge.net/)
6              
7             =head1 NAME
8              
9             Flash::FLAP::App::Executive
10              
11             =head1 DESCRIPTION
12              
13             Executive package figures out whether to call an explicitly
14             registered package or to look one up in a registered directory.
15             Then it executes the desired method in the package.
16              
17             =head1 CHANGES
18              
19             =head2 Sun Mar 23 13:27:00 EST 2003
20              
21             =over 4
22              
23             =item Synching with AMF-PHP:
24              
25             =item Replaced packagepath, packagename, packageConstruct with classpath, classname, classConstruct.
26              
27             =item Added _instanceName, _origClassPath and _headerFilter.
28              
29             =item Added subs setHeaderFilter(), setInstanceName()
30              
31             =item Renamed setClassPath to setTarget and removed extra junk from that function.
32              
33             =item Eliminated _getPackage() and _getMethod().
34              
35             =item Removed safeExecution().
36              
37             =back
38              
39             =head2 Tue Mar 11 21:59:27 EST 2003
40              
41             =item Passing @$a instead of $a to user functions. $a always is an array.
42              
43             =cut
44              
45              
46 1     1   5 use strict;
  1         1  
  1         30  
47 1     1   498 use Flash::FLAP::Util::RemotingService;
  1         12  
  1         986  
48              
49              
50             #The above variable declarations are not needed, as hash keys are used. They are useful just for the comments.
51             # the directory which should be used for the basic packages default "../"
52             # my $_basecp = "../";
53             # the classpath which is the path of the file from $_basecp
54             #my $_classpath;
55             # the string name of the package derived from the classpath
56             #my $_classname;
57             # the object we build from the package
58             #my $_classConstruct;
59             # the method to execute in the construct
60             #my $_methodname;
61             # the defined return type
62             #my $_returnType;
63             # the instance name to use for this gateway executive
64             #my $_instanceName;
65             # the list with registered service-packagees
66             #my $services = {};
67             # The original incoming classpath
68             #my $_target;
69             # The original classpath
70             #my $_origClassPath;
71             # switch to take different actions based on the header
72             #my $_headerFilter;
73            
74             # constructor
75             sub new
76             {
77 0     0 0   my ($proto)=@_;
78 0           my $self={};
79 0           bless $self, $proto;
80 0           return $self;
81             # nothing really to do here yet?
82             }
83              
84              
85             # setter for the _headerFilter
86             sub setHeaderFilter
87             {
88 0     0 1   my ($self, $header) = @_;
89 0           $self->{_headerFilter} = $header;
90             }
91              
92             # Set the base classpath. This is the path from which will be search for the packagees and functions
93             # $basecp should end with a "/";
94             sub setBaseClassPath
95             {
96 0     0 0   my ($self, $basecp) = @_;
97 0           $self->{_basecp} = $basecp;
98             }
99              
100             sub setInstanceName
101             {
102 0     0 1   my ($self, $name) = @_;
103 0           $self->{_instanceName} = $name;
104             }
105              
106             # you pass directory.script.method to this and it will build
107             # the classpath, classname and methodname values
108             sub setTarget
109             {
110 0     0 1   my ($self, $target)=@_;
111 0           $self->{target} = $target;
112             # grab the position of the last . char
113 0           my $lpos = strrpos($target, ".");
114             # there were none
115 0 0         unless ($lpos)
116             {
117 0           print STDERR "Service name $target does not contain a dot.\n";
118             # throw an error because there has to be atleast 1
119             }
120             else
121             {
122             # the method name is the very last part
123 0           $self->{_methodname} = substr($target, $lpos+1);
124             }
125             # truncate the method name from the string
126 0           my $trunced = substr($target, 0, $lpos);
127            
128 0           $self->{_classname} = $trunced;
129             }
130              
131             sub registerService
132             {
133 0     0 0   my ($self, $package, $servicepackage) = @_;
134 0           $self->{services}->{$package} = $servicepackage;
135             }
136              
137             # returns the return type for this method
138             sub getReturnType
139             {
140 0     0 0   my ($self)=@_;
141 0           return $self->{_returnType};
142             }
143              
144             # execute the method using dynamic inclusion of Perl files
145             sub doMethodCall
146             {
147 0     0 0   my ($self, $a) = @_;
148            
149             #First try to call a registered class...
150 0           my $package = $self->{_classname};
151 0           my $method = $self->{_methodname};
152            
153 0           my $calledMethod = $method;
154            
155 0 0         if(exists $self->{services}->{$package})
156             {
157 0           return $self->doMethodCall_registered($package, $method, $a);
158             }
159            
160             #Otherwise, browse in the directory specified by the user.
161              
162 0           push @INC, $self->{_basecp};
163              
164             # build the class object
165            
166 0           $package =~ s#\.#::#g;
167            
168 0 0         unless (eval ("require " . $package))
169             {
170             # report back to flash that the class wasn't properly formatted
171 0           print STDERR "Class $package does not exist or could not be loaded.\n";
172 0           print STDERR $@;
173 0           return;
174             }
175              
176             # build the construct from the extended class
177 0           my $object = $package->new;
178            
179             # Check to see if the DescribeService header has been turned on
180 0 0 0       if ($self->{_headerFilter} && $self->{_headerFilter} eq "DescribeService")
181             {
182 0           my $wrapper = new Flash::FLAP::Util::RemotingService($package, $object);
183              
184 0           $self->{_classConstruct} = $wrapper;
185              
186 0           $method = "__describeService";
187              
188             # override the method name to the __describeService method
189 0           $self->{_methodname} = $method;
190              
191             # add the instance to the methodrecord to control registered discover
192 0           my $methodTable = $self->{_classConstruct}->methodTable;
193 0           $methodTable->{$method}{'instance'} = $self->{_instanceName};
194              
195             }
196             else
197             {
198 0           $self->{_classConstruct} = $object;
199             }
200              
201             # was this defined in the methodTable -- required to enable FLAP service approach
202 0 0         if (exists ($self->{_classConstruct}->methodTable->{$method}))
203             {
204             # create a shortcut to the methodTable
205 0           my %methodrecord = %{$self->{_classConstruct}->methodTable->{$method}};
  0            
206              
207             # check to see if this method name is aliased
208 0 0         if (exists ($methodrecord{'alias'}))
209             {
210             # map the _methodname to the alias
211 0           $method = $methodrecord{'alias'};
212             }
213              
214 0 0         if (exists($methodrecord{'instance'}))
215             {
216             # check the instance names to see if they match. If so, then let this happen
217 0 0 0       if (!exists($methodrecord{'instance'}) || $self->{_instanceName} != $methodrecord{'instance'})
218             {
219             # if they don't match then print STDERR with this error
220 0           print STDERR "Access error for " . $self->{_headerFilter} . ".\n";
221 0           return;
222             }
223             }
224            
225             # check to see if an explicit return type was defined
226 0 0         if (exists($methodrecord{'returns'}))
227             {
228 0           $self->{_returnType} = $methodrecord{'returns'};
229             }
230             # set the default return type of "unknown"
231             else
232             {
233 0           $self->{_returnType} = "unknown";
234             }
235             # set to see if the access was set and the method as remote permissions.
236 0 0 0       if ( (exists($methodrecord{'access'})) && (lc ($methodrecord{'access'}) eq "remote"))
237             {
238             # finally check to see if the method existed
239 0 0         if ($self->{_classConstruct}->can($method))
240             {
241             # execute the method and return it's results to the gateway
242 0           return $self->{_classConstruct}->$method(@$a);
243             }
244             else
245             {
246             # print STDERR with error
247 0           print STDERR "Method " . $calledMethod . " does not exist in class ".$self->{_classConstruct}.".\n";
248             }
249             }
250             else
251             {
252             # print STDERR with error
253 0           print STDERR "Access Denied to " . $calledMethod . "\n";
254             }
255            
256            
257             }
258             else
259             {
260             # print STDERR with error
261 0           print STDERR "Function " . $calledMethod . " does not exist in class ".$self->{_classConstruct}.".\n";
262             }
263              
264             }
265              
266             sub doMethodCall_registered
267             {
268 0     0 0   my ($self, $package, $method, $a) = @_;
269            
270 0           my $serviceobject = $self->{services}->{$package};
271              
272 0 0         if(length($package) == 0)
    0          
    0          
273             {
274             # TODO: handle non packaged functions
275             #trigger_error("ERROR: no package in call",E_USER_ERROR);
276 0           return;
277             }
278             elsif(!$serviceobject)
279             {
280 0           print STDERR "Package ".$package." not registerd on server\n";
281 0           return;
282             }
283             elsif(!$serviceobject->can($method))
284             {
285 0           print STDERR "Function ".$method." does not exist in package ".$package."\n";
286 0           return;
287             }
288             else
289             {
290 0           $self->{_returnType} = "unknown";
291 0           return $serviceobject->$method(@$a);
292             }
293             }
294              
295             sub strrpos
296             {
297 0     0 0   my ($string)=@_;
298 0           my $reversed = reverse $string;
299 0           my $firstDotIndex = index($reversed, ".");
300 0           return length($string)-$firstDotIndex-1;
301             }
302              
303             1;