changeset 241:f48a1a9f4fa2

+Added ViewResult to allow implementation of the view environment. *TTDocuments now storing creation parameters *TTControls automatically propagating layout and title meta to their attributes +Added UnauthorizaedException web exception *minor fixes
author sergey
date Thu, 18 Oct 2012 04:49:55 +0400
parents abc7c26bf615
children fe9d62d9054d
files Lib/IMPL/DOM/Schema/Node.pm Lib/IMPL/Web/Handler/JSONView.pm Lib/IMPL/Web/Handler/TTView.pm Lib/IMPL/Web/UnauthorizedException.pm Lib/IMPL/Web/View/TTControl.pm Lib/IMPL/Web/View/TTDocument.pm Lib/IMPL/Web/ViewResult.pm Lib/IMPL/lang.pm
diffstat 8 files changed, 115 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Schema/Node.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/DOM/Schema/Node.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -57,6 +57,18 @@
     }
 }
 
+sub isOptional {
+    my ($this) = @_;
+    
+    return $this->{$minOccur} ? 0 : 1;
+}
+
+sub isMultiple {
+    my ($this) = @_;
+    
+    return ($this->{$maxOccur} eq 'unbounded' || $this->{$maxOccur} > 1 ) ? 1 : 0; 
+}
+
 sub inflateValue {
     $_[1];
 }
--- a/Lib/IMPL/Web/Handler/JSONView.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/Web/Handler/JSONView.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -4,7 +4,8 @@
 
 use IMPL::declare {
     require => {
-        HttpResponse => 'IMPL::Web::HttpResponse'        
+        HttpResponse => 'IMPL::Web::HttpResponse',
+        ViewResult => '-IMPL::Web::ViewResult'        
     },
 	base => [
 		'IMPL::Object' => undef,
@@ -21,14 +22,18 @@
 	my ($this,$action,$next) = @_;
 	
 	my $result = $next ? $next->($action) : undef;
-	$result = [$result] unless ref $result;
+	
 	
-	$action->response->contentType($this->contentType);
-    
+	my $model = ( ref $result and eval { $result->isa(ViewResult) } )
+	   ? $result->model
+	   : $result;
+	
+	$model = [$model] unless ref $model;
+	
     return HttpResponse->new({
         type => $this->contentType,
         charset => 'utf-8',             
-        body => JSON->new->utf8->pretty->encode($result)
+        body => JSON->new->utf8->pretty->encode($model)
     });
 }
 
--- a/Lib/IMPL/Web/Handler/TTView.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/Web/Handler/TTView.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -6,7 +6,9 @@
 use IMPL::declare {
     require => {
         Factory      => 'IMPL::Web::View::ObjectFactory',
-        HttpResponse => 'IMPL::Web::HttpResponse'
+        HttpResponse => 'IMPL::Web::HttpResponse',
+        Loader       => 'IMPL::Code::Loader',
+        ViewResult   => '-IMPL::Web::ViewResult'
       },
       base => [
         'IMPL::Object'               => undef,
@@ -36,20 +38,27 @@
     my ( $this, $action, $next ) = @_;
 
     my $result = $next ? $next->($action) : undef;
+    
+    my ($model,$view);
+    if( ref $result and eval { $result->isa(ViewResult) } ) {
+        $model = $result->model;
+        $view = $result;      
+    } else {
+        $model = $result;
+        $view = ViewResult->new(model => $model);
+    }
+    
 
     my $vars = {
-        model       => $result,
+        view        => $view,
+        model       => $model,
         action      => $action,
         app         => $action->application,
         ImportClass => sub {
             my $class = shift;
 
-            my $module = $class;
-
-            $module =~ s/::/\//g;
-            $module .= ".pm";
-
-            require $module;
+            $class = Loader->safe->Require($class);
+            
             return Factory->new($class);
         }
     };
@@ -61,7 +70,7 @@
     return HttpResponse->new(
         type => $this->contentType,
         charset => $this->contentCharset,
-        body => $doc->Render($vars)
+        body => $doc->Render()
     );
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/Web/UnauthorizedException.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -0,0 +1,24 @@
+package IMPL::Web::UnauthorizedException;
+use strict;
+
+use IMPL::declare {
+	base => {
+		'IMPL::Web::Exception' => '@_'
+	}
+};
+
+sub status {
+	"401 Unauthorized"
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+C<IMPL::Web::UnauthorizedException> - запрос требует идентификации пользователя.
+
+=cut
\ No newline at end of file
--- a/Lib/IMPL/Web/View/TTControl.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/Web/View/TTControl.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -2,6 +2,8 @@
 use strict;
 
 use IMPL::Const qw(:prop);
+use IMPL::lang qw(:hash);
+use Scalar::Util qw(blessed);
 use IMPL::declare {
 	require => {
         TTContext => 'Template::Context',
@@ -10,7 +12,7 @@
         OperationException => '-IMPL::InvalidOperationException'
 	},
 	base => [
-	   'IMPL::Object' => '@_'
+	   'IMPL::Object' => undef
 	],
 	props => [
 	   id => PROP_RO,
@@ -30,6 +32,7 @@
 }
 
 our $AutoloadRegex = qr/^[a-z]/;
+our @REFLECT_META = qw(title layout);
 
 sub CTOR {
     my ($this,$name,$template,$context,$refProps) = @_;
@@ -44,11 +47,20 @@
     $this->name($name);
     $this->attributes({});
     
-    if (ref $refProps eq 'HASH') {
-        while (my($key,$value) = each %$refProps) {
-            $this->SetAttribute($key,$value);
+    my %attrs;
+    
+    foreach my $meta ( @REFLECT_META ) {
+        next if $meta =~ /^_/;
+        if( my $value = $template->$meta() ) {
+            $attrs{$meta} = $value;
         }
     }
+    
+    hashApply(\%attrs,$refProps) if ref $refProps eq 'HASH';
+    
+    while (my($key,$value) = each %attrs) {
+        $this->SetAttribute($key,$value);
+    }
 }
 
 sub InitInstance {
@@ -94,7 +106,7 @@
     $args = {} unless ref $args eq 'HASH';
     
     if(my $body = $this->GetRenderBlock ) {
-        return $this->context->include( $body, { %$args, this => $this, template => $this->template, document => $this->document } );
+        return $this->context->include( $body, { %$args, this => $this, template => $this->template } );
     } else {
         return "";
     }    
@@ -109,6 +121,8 @@
     
     if ($method =~ /$AutoloadRegex/) {
         my $this = shift;
+        
+        die OperationException->new("can't invoke method '$method' on an unblessed reference") unless blessed $this;
     
         return @_ ? $this->SetAttribute($method,@_) : $this->GetAttribute($method);
     } else {
--- a/Lib/IMPL/Web/View/TTDocument.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/Web/View/TTDocument.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -3,6 +3,7 @@
 
 use Scalar::Util qw(weaken);
 use IMPL::Const qw(:prop);
+use IMPL::lang qw(:hash);
 
 use IMPL::declare {
     require => {
@@ -23,6 +24,7 @@
         opts => PROP_RO,
         loader => PROP_RW,
         controls => PROP_RO,
+        creationArgs => PROP_RO,
         
         # store the stash separately to make require() method to work correctly
         # even when a stash of the context is modified during the processing 
@@ -44,17 +46,20 @@
     
     $this->opts($refOpts);
     $this->stash($this->context->stash);
+    $this->creationArgs($vars);
     
     my $self = $this;
     weaken($self);
     
-    $this->templateVars('require', sub {
+    $this->templateVars(require => sub {
         my $doc = $self;
         die new IMPL::Exception("A document is destroyed or invalid") unless $doc;
         $doc->RequireControl(@_);
     });
     
-    $this->templateVars('document', sub { $self } );
+    $this->templateVars(context => $vars);
+    
+    $this->templateVars(document => sub { $self } );
     $this->InitInstance($vars);
 }
 
@@ -114,23 +119,23 @@
 sub Render {
     my ($this,$args) = @_;
     
-    my $output;
+    $args ||= {};
+    
+    my $newArgs = hashMerge($this->creationArgs, $args);
     
     if ($this->layout) {
-        $output = $this->context->include(
+        return $this->context->include(
             $this->loader->layout($this->layout),
             {
-            	%{$args || {}},
-                content => sub { $this->RenderContent($args); },
+            	%{$newArgs},
+                content => sub { $this->RenderContent($newArgs); },
                 this => $this,
                 template => $this->template
             }
         );
     } else {
-        return $this->RenderContent($args);
+        return $this->RenderContent($newArgs);
     }
-    
-    return $output;
 }
 
 sub RenderContent {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/Web/ViewResult.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -0,0 +1,16 @@
+package IMPL::Web::ViewResult;
+use strict;
+
+use IMPL::Const qw(:prop);
+
+use IMPL::declare {
+    base => [
+        'IMPL::Object' => undef,
+        'IMPL::Object::Autofill' => '@_'
+    ],
+    props => [
+        model => PROP_RW
+    ]
+};
+
+1;
\ No newline at end of file
--- a/Lib/IMPL/lang.pm	Wed Oct 17 17:41:29 2012 +0400
+++ b/Lib/IMPL/lang.pm	Thu Oct 18 04:49:55 2012 +0400
@@ -160,6 +160,8 @@
 sub hashApply {
     my ($target,$diff) = @_;
     
+    return $target unless ref $diff eq 'HASH';
+    
     while ( my ($key,$value) = each %$diff) {
         $key =~ /^(\+|-)?(.*)$/;
         my $op = $1 || '+';