Author: spadkins
Date: Wed May 21 11:29:24 2008
New Revision: 11299

Modified:
   p5ee/trunk/App-Context/CHANGES
   p5ee/trunk/App-Context/lib/App/Context.pm
   p5ee/trunk/App-Context/lib/App/Context/HTTP.pm
   p5ee/trunk/App-Context/lib/App/Request/CGI.pm

Log:
added the ability to do RPC

Modified: p5ee/trunk/App-Context/CHANGES
==============================================================================
--- p5ee/trunk/App-Context/CHANGES      (original)
+++ p5ee/trunk/App-Context/CHANGES      Wed May 21 11:29:24 2008
@@ -2,6 +2,13 @@
 # CHANGE LOG
 #########################################
 
+VERSION 0.967 (not yet released)
+ x App::Storable         - protect against varying versions of Storable which 
may cause deserialization exceptions
+ x App::Serializer::Json - read and write JSON
+ x App::Serializer::Html - serialize output as HTML for debugging/viewing
+ x App::Context::HTTP    - add support for RPC and REST (in addition to web 
app support)
+ x App::Context::service_exists() - detect if a service exists in the 
config/session (generalizes session_object_exists())
+
 VERSION 0.9661
  x updated the dependencies so that the CPAN tests don't fail
 

Modified: p5ee/trunk/App-Context/lib/App/Context.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Context.pm   (original)
+++ p5ee/trunk/App-Context/lib/App/Context.pm   Wed May 21 11:29:24 2008
@@ -811,7 +811,6 @@
 =cut
 
 # Standard Services: provided in the App-Context distribution
-sub serializer          { my $self = shift; return 
$self->service("Serializer",@_); }
 sub call_dispatcher     { my $self = shift; return 
$self->service("CallDispatcher",@_); }
 sub message_dispatcher  { my $self = shift; return 
$self->service("MessageDispatcher",@_); }
 sub resource_locker     { my $self = shift; return 
$self->service("ResourceLocker",@_); }
@@ -821,6 +820,22 @@
 sub session_object      { my $self = shift; return 
$self->service("SessionObject",@_); }
 sub value_domain        { my $self = shift; return 
$self->service("ValueDomain",@_); }
 
+sub serializer          {
+    my $self = shift;
+    my $name = shift;
+    my (@args);
+    if ($#_ > -1 || !$name || $self->service_exists("Serializer", $name)) {
+        @args = @_;
+    }
+    else {
+        my $class_base = ucfirst(lc($name));
+        $class_base =~ s/_([a-z])/"_" . uc($1)/eg;
+        my $class = "App::Serializer::" . $class_base;
+        @args = (class => $class);
+    }
+    return $self->service("Serializer", $name, @args);
+}
+
 # Extended Services: provided in the App-Widget and App-Repository 
distributions
 # this is kind of cheating for the core to know about the extensions, but OK
 sub template_engine     { my $self = shift; return 
$self->service("TemplateEngine",@_); }
@@ -903,6 +918,37 @@
     return $exists;
 }
 
+sub service_exists {
+    &App::sub_entry if ($App::trace);
+    my ($self, $service_type, $service_name) = @_;
+    my ($exists, $service_template, $service_class);
+
+    $service_class =
+        $self->{session}{cache}{$service_type}{$service_name}{class} ||
+        $self->{session}{store}{$service_type}{$service_name}{class} ||
+        $self->{conf}{$service_type}{$service_name}{class};
+
+    if (!$service_class) {
+
+        $service_template =
+            $self->{session}{cache}{$service_type}{$service_name}{type} ||
+            $self->{session}{store}{$service_type}{$service_name}{type} ||
+            $self->{conf}{$service_type}{$service_name}{type};
+
+        if ($service_template) {
+            $service_class = 
$self->{conf}{"${service_type}Type"}{$service_template}{class};
+        }
+    }
+
+    $exists = $service_class ? 1 : 0;
+
+    $self->dbgprint("Context->service_exists($service_name) = $exists")
+        if ($App::DEBUG && $self->dbg(2));
+
+    &App::sub_exit($exists) if ($App::trace);
+    return $exists;
+}
+
 #############################################################################
 # PUBLIC METHODS
 #############################################################################

Modified: p5ee/trunk/App-Context/lib/App/Context/HTTP.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Context/HTTP.pm      (original)
+++ p5ee/trunk/App-Context/lib/App/Context/HTTP.pm      Wed May 21 11:29:24 2008
@@ -145,17 +145,23 @@
         my $user = $self->user();
         my $authorization = $self->authorization();
         my $events = $self->{events};
-        my ($event, $service_type, $service_name, $method, $args);
+        my ($event, $service_type, $service_name, $method, $args, 
$return_results, $return_event_results, $event_results);
         my $results = "";
         # my $display_current_widget = 1;
 
         while ($#$events > -1) {
             $event = shift(@$events);
-            ($service_type, $service_name, $method, $args) = @$event;
+            ($service_type, $service_name, $method, $args, 
$return_event_results) = @$event;
             if 
($authorization->is_authorized("/App/$service_type/$service_name/$method", 
$user)) {
-                $results = $self->call($service_type, $service_name, $method, 
$args);
-                $args = join(",", @$args) if (ref($args) eq "ARRAY");
-                
$self->lap_timer("$service_type($service_name).$method($args)") if ($timer);
+                $event_results = $self->call($service_type, $service_name, 
$method, $args);
+                if ($return_event_results) {
+                    $results = $event_results;
+                    $return_results = 1;
+                }
+                if ($timer) {
+                    my $args_str = (ref($args) eq "ARRAY") ? join(",", @$args) 
: $args;
+                    
$self->lap_timer("$service_type($service_name).$method($args_str)");
+                }
                 $user = $self->user();
             }
         }
@@ -174,7 +180,7 @@
             }
         }
 
-        $results = $self->service($service_type, $service_name);
+        $results = $self->service($service_type, $service_name) if 
(!$return_results);
 
         my $response = $self->response();
         my $ref = ref($results);
@@ -216,42 +222,6 @@
     &App::sub_exit() if ($App::trace);
 }
 
-# this code needs to be restored at the Context->dispatch_events() level
-#       $name = $context->so_get("default", "name");
-#       $service = $context->so_get("default", "service");
-#       $returntype = $context->so_get("default", "returntype");
-#       # print "name=[$curr_name] service=[$curr_service] 
returntype=[$curr_returntype]\n";
-# ...
-#       $context->so_set("default", "curr_service", $curr_service);
-#       $context->so_set("default", "curr_name",    $curr_name);
-#       # $context->so_set("default", "curr_method",  $curr_method);
-#       # $context->so_set("default", "curr_args",    $curr_args);
-#       $context->so_set("default", "curr_returntype",    $curr_returntype);
-# ...
-#       if ($service) {
-#           my $service = $context->service($service, $name);
-#           my $response = $context->response();
-#           if (!$service) {
-#               $response->content("Service not defined: $service($name)\n");
-#           }
-#           elsif (!$service->can($method)) {
-#               $response->content("Method not defined on Service: 
$service($name).$method($args)\n");
-#           }
-#           else {
-#               my @results = $service->$method($args);
-#               if ($#results == -1) {
-#                   $response->content($service->internals());
-#               }
-#               elsif ($#results == 0) {
-#                   $response->content($results[0]);
-#                   $response->content_type($service->content_type());
-#               }
-#               else {
-#                   $response->content([EMAIL PROTECTED]);
-#               }
-#           }
-#       }
-
 sub send_error {
     &App::sub_entry if ($App::trace);
     my ($self, $errmsg) = @_;
@@ -347,57 +317,23 @@
 
 =cut
 
-#sub send_results {
-#    my ($self, $results) = @_;
-#
-#    my ($serializer, $returntype);
-#
-#    if (ref($results)) {
-#        $returntype = $self->{returntype};
-#        $serializer = $self->serializer($returntype);
-#        $results = $serializer->serialize($results);
-#    }
-#
-#    if ($self->{messages}) {
-#        my $msg = $self->{messages};
-#        $self->{messages} = "";
-#        $msg =~ s/<br>/\n/g;
-#        print $msg;
-#    }
-#    else {
-#        print $results;
-#    }
-#}
-#
-#sub send_error {
-#    my ($self, $errmsg) = @_;
-#    print <<EOF;
-#-----------------------------------------------------------------------------
-#AN ERROR OCCURRED in App::Context->dispatch_events()
-#-----------------------------------------------------------------------------
-#$errmsg
-#
-#-----------------------------------------------------------------------------
-#Additional messages from earlier stages may be relevant if they exist below.
-#-----------------------------------------------------------------------------
-#$self->{messages}
-#EOF
-#}
-
 sub send_response {
     &App::sub_entry if ($App::trace);
     my $self = shift;
 
-    my ($serializer, $response, $ctype, $content, $content_type, $headers);
-    $response     = $self->response();
-    $content      = $response->content();
+    my ($serializer, $response, $content, $content_type, $headers);
+    $response = $self->response();
+    $content  = $response->content();
 
+    # NOTE: $content will be a scalar if HTML is being returned
     if (ref($content)) {
-        $ctype = $self->so_get("default", "ctype", "default");
-        $serializer = $self->serializer($ctype);
+        my $request    = $self->request();
+        my $returntype = $request->get_returntype();
+        $serializer = $self->serializer($returntype);
         $content = $serializer->serialize($content);
         $content_type = $serializer->serialized_content_type();
     }
+
     $content_type = $response->content_type() if (!$content_type);
     $content_type = "text/plain" if (!$content_type);
     $headers      = "Content-type: $content_type\n";

Modified: p5ee/trunk/App-Context/lib/App/Request/CGI.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Request/CGI.pm       (original)
+++ p5ee/trunk/App-Context/lib/App/Request/CGI.pm       Wed May 21 11:29:24 2008
@@ -280,7 +280,7 @@
             # Note: the <returntype> is found in another location when it is 
needed
             # here, we simply need to delete the trailing :<returntype> or 
.<returntype>
             $path_info =~ s!:[a-zA-Z0-9_]+$!!;  # delete trailing :<returntype>
-            $path_info =~ s!\.(html|xml|yaml|csv|pdf|perl)$!!;  # delete 
trailing .<returntype>
+            $path_info =~ s!\.(html|xml|yaml|csv|pdf|perl|json)$!!;  # delete 
trailing .<returntype>
 
             if ($path_info =~ s!^/([A-Z][A-Za-z0-9]*)/!/!) {
                 $service = $1;
@@ -349,9 +349,24 @@
 
             if ($service && $name && $method) {
                 $temp    = $cgi->param("args");
-                $args    = $temp if ($temp);
-
-                if (defined $args && !ref($args)) {
+                if ($temp) {
+                    $args = $temp;
+                    if ($args =~ /^\s*$/) {
+                        $args = [];
+                    }
+                    else {
+                        my $argstype = $cgi->param("argstype") || 
$self->get_returntype();
+                        my ($ser);
+                        if ($argstype) {
+                            $ser = $context->serializer($argstype);
+                        }
+                        else {
+                            $ser = $context->serializer("one_line", class => 
"App::Serializer::OneLine");
+                        }
+                        $args = $ser->deserialize($args);
+                    }
+                }
+                elsif (defined $args && !ref($args)) {
                     if ($args =~ /^\s*$/) {
                         $args = [];
                     }
@@ -363,7 +378,7 @@
                 if (!$options->{open_widget_urls} && (!$permissions || 
!$permissions->{$method})) {
                     die "Not permitted to perform the [$method] method on the 
[$name] widget\n";
                 }
-                push(@events, [ $service, $name, $method, $args ]);
+                push(@events, [ $service, $name, $method, $args, 1 ]);
             }
             elsif ($service && $name) {
                 if (!$options->{open_widget_urls} && (!$permissions || 
!$permissions->{view})) {
@@ -466,7 +481,7 @@
                 if ($args eq "") {
                     # do nothing, @args = ()
                 }
-                elsif ($args =~ /\{/) {  # } balance
+                elsif ($args =~ /\{/) {
                     foreach $arg (split(/ *, */,$args)) {
                         if ($arg =~ /^\{(.*)\}$/) {
                             push(@args, $context->so_get($1));
@@ -571,22 +586,26 @@
     &App::sub_entry if ($App::trace);
     my ($self, $cgi) = @_;
 
-    if (!defined $cgi) {
-        $cgi = $self->{cgi};
-    }
-    elsif (!defined $self->{cgi}) {
-        $self->{cgi} = $cgi;
-    }
-    my ($returntype);
-    if ($cgi) {
-        $returntype = $cgi->param("returntype");
-    }
+    my $returntype = $self->{returntype};
     if (!$returntype) {
+        if (!defined $cgi) {
+            $cgi = $self->{cgi};
+        }
+        elsif (!defined $self->{cgi}) {
+            $self->{cgi} = $cgi;
+        }
+        if ($cgi) {
+            $returntype = $cgi->param("returntype");
+        }
         my $context = $self->{context};
         my $path_info = $ENV{PATH_INFO};
         if ($path_info =~ /:([a-zA-Z0-9_]+)$/) {
             $returntype = $1;
         }
+        elsif ($path_info =~ m!\.(html|xml|yaml|csv|pdf|perl|json)$!) {
+            $returntype = $1;
+        }
+        $self->{returntype} = $returntype;
     }
     &App::sub_exit($returntype) if ($App::trace);
     return($returntype);

Reply via email to