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