view Lib/IMPL/Web/Handler/RestController.pm @ 199:e743a8481327

Added REST support for forms (with only get and post methods)
author sergey
date Mon, 23 Apr 2012 01:36:52 +0400
parents 2ffe6f661605
children 5146e17a7b76
line wrap: on
line source

package IMPL::Web::Handler::RestController;
use strict;

use IMPL::lang qw(:declare :constants);


use IMPL::declare {
	require => {
		Exception => 'IMPL::Exception',
		ArgumentExecption => '-IMPL::InvalidArgumentException',
		HttpException => 'IMPL::Web::Exception',
        NotFoundException => 'IMPL::Web::NotFoundException'
	},
	base => {
		'IMPL::Object' => undef,
		'IMPL::Object::Autofill' => '@_',
		'IMPL::Object::Serializable' => undef
	}	
};

BEGIN {
	public property root => PROP_GET | PROP_OWNERSET;
	public property contract => PROP_GET | PROP_OWNERSET;
	public property types => PROP_GET | PROP_OWNERSET;
}

sub CTOR {
	my ($this) = @_;
	
	die ArgimentException->new("types")
	   if $this->types and ref $this->types ne 'HASH'; 
}

sub Invoke {
	my ($this,$action) = @_;
	
	my $query = $action->query;
	
	my $method = $query->request_method;
	
	#TODO: path_info is broken for IIS
	my $pathInfo = $query->path_info;
	
	my @segments = split /\//, $pathInfo, -1; # keep trailing empty string if present
	
	# remove first segment since it's always empty
	shift @segments;
	
	my ($obj,$view) = (pop(@segments) =~ m/(.*?)(?:\.(\w+))?$/);
	
	if ($this->types and my $type = $this->types->{$view}) {
        $action->response->contentType($type);		
	}
	
	my $res = $this->contract->Transform($this->root, { id => '' } );
	
	while(@segments) {
		my $id = shift @segments;
		$res = $this->contract->Transform( $res->InvokeHttpMethod('GET',$id,$action), { parent => $res, id => $id } );
		
		die NotFoundException->new() unless $res;
	}
	
	$res = $res->InvokeHttpMethod($method,$obj,$action);
}

1;

__END__

=pod

=head1 NAME

=head1 SYNOPSIS

=head1 DESCRIPTION

Использует C<$ENV{PATH_INFO}> для получения ресурса и вызова метода.


=cut