diff Lib/IMPL/Web/Application.pm @ 198:2ffe6f661605

Implemented IMPL::Web::Handler::RestController fixes in IMPL::Serialization completed IMPL::Web::Application::RestResource added IMPL::Web::Handler::JSONView added IMPL::Web::RestContract
author cin
date Fri, 20 Apr 2012 16:06:36 +0400
parents 4d0e1962161c
children d6e2ea24af08
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application.pm	Thu Apr 19 02:10:02 2012 +0400
+++ b/Lib/IMPL/Web/Application.pm	Fri Apr 20 16:06:36 2012 +0400
@@ -2,29 +2,46 @@
 use strict;
 use warnings;
 
-use parent qw(IMPL::Config IMPL::Object::Singleton);
+use IMPL::lang qw(:declare :constants);
+use CGI;
+use Carp qw(carp);
 
-require IMPL::Web::Application::Action;
-require IMPL::Web::Application::Response;
-
-use IMPL::Class::Property;
-use CGI;
+use IMPL::declare {
+	require => {
+        TAction => 'IMPL::Web::Application::Action',
+        TResponse => 'IMPL::Web::Application::Response',
+        TFactory => '-IMPL::Object::Factory'
+	},
+	base => {
+		'IMPL::Config' => '@_',
+		'IMPL::Object::Singleton' => '@_'
+	}
+};
 
-__PACKAGE__->PassThroughArgs;
+BEGIN {
+	public property handlerError => PROP_ALL;
+	public property actionFactory => PROP_ALL;
+	public property handlers => PROP_ALL | PROP_LIST;
+	public property responseCharset => PROP_ALL;
+	public property security => PROP_ALL;
+	public property options => PROP_ALL;
+	public property fetchRequestMethod => PROP_ALL;
+}
 
-public property handlerError => prop_all;
-public property actionFactory => prop_all;
-public property handlersQuery => prop_all | prop_list;
-public property responseCharset => prop_all;
-public property security => prop_all;
-public property options => prop_all;
-public property fetchRequestMethod => prop_all;
+
+#TODO: remove
+sub handlersQuery {
+	carp "handlersQuery is obsolete use handlers instead";
+	goto &handlers;
+}
 
 
 sub CTOR {
     my ($this) = @_;
     
-    $this->actionFactory(typeof IMPL::Web::Application::Action) unless $this->actionFactory;
+    die IMPL::InvalidArgumentException->new("handlers","At least one handler should be supplied") unless $this->handlers->Count;
+    
+    $this->actionFactory(TAction) unless $this->actionFactory;
     $this->responseCharset('utf-8') unless $this->responseCharset;
     $this->fetchRequestMethod(\&defaultFetchRequest) unless $this->fetchRequestMethod;
     $this->handlerError(\&defaultHandlerError) unless $this->handlerError;
@@ -33,6 +50,10 @@
 sub Run {
     my ($this) = @_;
     
+    my $handler;
+    
+    $handler = _ChainHandler($_,$handler) foreach $this->handlers;
+    
     while (my $query = $this->FetchRequest()) {
         
         my $action = $this->actionFactory->new(
@@ -43,9 +64,7 @@
         eval {
             $action->response->charset($this->responseCharset);
             
-            $action->ChainHandler($_) foreach $this->handlersQuery;
-            
-            $action->Invoke();
+            $handler->($action);
             
             $action->response->Complete;
         };
@@ -57,6 +76,45 @@
     }
 }
 
+sub _ChainHandler {
+	my ($handler,$next) = @_;
+	
+	if (ref $handler eq 'CODE') {
+		return sub {
+			my ($action) = @_;
+			return $handler->($action,$next);
+		};
+	} elsif (eval { $handler->can('Invoke') } ) {
+		return sub {
+			my ($action) = @_;
+			return $handler->Invoke($action,$next);
+		};
+	} elsif (eval{ $handler->isa(TFactory) }) {
+		return sub {
+			my ($action) = @_;
+			my $inst = $handler->new();
+			return $inst->Invoke($action,$next);
+		}
+	} elsif ($handler and not ref $handler and $handler =~ m/^(-)?(\w+(?:::\w+)*)$/) {
+		my $class = $2;
+		if (not $1) {
+			my $mod = $class;
+			$mod =~ s/::/\//g;
+			require "$mod.pm";
+			
+			die IMPL::InvalidArgumentException->("An invalid handler supplied",$handler) unless $class->can('Invoke');
+		}
+		
+		return sub {
+			my ($action) = @_;
+			my $inst = $class->new();
+			return $inst->Invoke($action,$next);
+		};
+	} else {
+		die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler);
+	}
+}
+
 sub FetchRequest {
     my ($this) = @_;