Mercurial > pub > Impl
diff Lib/IMPL/Web/Handler/ViewSelector.pm @ 206:c8fe3f84feba
+IMPL::Web::Handlers::ViewSelector
+IMPL::Web::Handlers::ErrorHandler
*IMPL::Web::Handlers::RestController moved types mappings to ViewSelector
author | sergey |
---|---|
date | Thu, 03 May 2012 16:48:39 +0400 |
parents | |
children | 3d433a977e3b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Web/Handler/ViewSelector.pm Thu May 03 16:48:39 2012 +0400 @@ -0,0 +1,60 @@ +package IMPL::Web::Handler::ViewSelector; +use strict; + +use IMPL::lang qw(:declare :constants); + +use IMPL::declare { + require => { + NotAcceptable => 'IMPL::Web::NotAcceptableException' + }, + base => { + 'IMPL::Object' => undef, + 'IMPL::Object::Autofill' => '@_', + 'IMPL::Object::Serializable' => undef + } +}; + +BEGIN { + public property views => PROP_ALL | PROP_LIST; + public property fallback => PROP_ALL; + public property types => PROP_ALL; +} + +sub Invoke { + my ($this,$action,$next) = @_; + + my $handler; + my $path = $action->query->path_info; + + if ($this->types and $path =~ m/\.(\w+)$/) { + my $forced; + if ($forced = $this->types->{$1} and $action->query->Accept($forced) ) { + ($handler) = grep eval { $_->can('contentType') } && $_->contentType eq $forced, $this->views; + } + } + + if (not $handler) { + + my @handlers = + sort { + $b->{preference} <=> $a->{preference} + } map { + { + handler => $_, + preference => + eval { $_->can('contentType') } ? $action->query->Accept($_->contentType) : 0 + } + } $this->views; + + my $info = shift @handlers; + $handler = $info ? $info->{handler} : undef; + + } + + die NotAcceptable->new(map { eval {$_->can('contentType') } ? $_->contentType : () } $this->views ) + unless $handler; + + return $handler->Invoke($action,$next); +} + +1; \ No newline at end of file