Mercurial > pub > Impl
diff lib/IMPL/Web/AutoLocator.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Web/AutoLocator.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,241 @@ +package IMPL::Web::AutoLocator; +use strict; + +use overload '""' => 'toString'; + +use IMPL::Const qw(:prop); +use IMPL::lang qw(:hash); +use IMPL::clone qw(clone); +use URI; +use URI::Escape; +use IMPL::declare { + require => { + Exception => 'IMPL::Exception', + ArgumentException => '-IMPL::InvalidArgumentException' + }, + base => [ + 'IMPL::Object' => undef, + 'IMPL::Object::Autofill' => '@_', + 'IMPL::Object::Serializable' => '@_' + ], + props => [ + base => PROP_RO, + view => PROP_RW, + query => PROP_RW, + hash => PROP_RW + ] +}; + +sub Clone { + my $this = shift; + + return clone($this); +} + +sub Child { + my $this = shift; + my $child = shift or die ArgumentException->new("a child resource identifier is required"); + die ArgumentException->new("a child resource can't be a reference") if ref $child; + + # safe + #$child = uri_escape_utf8($child); + + my %args; + + $args{base} = $this->base =~ /\/$/ ? $this->base . $child : $this->base . '/' . $child; + $args{view} = $this->view if $this->view; + $args{hash} = $this->hash if $this->hash; + + if (@_) { + my $query = shift; + + $args{query} = ref $query eq 'HASH' ? hashMerge($this->query,$query) : $query; + } + + return $this->new(%args); +} + +sub Sibling { + my $this = shift; + my $child = shift or die ArgumentException->new("a child resource identifier is required"); + die ArgumentException->new("a child resource can't be a reference") if ref $child; + + # safe + #$child = uri_escape($child); + + my %args; + + if($this->base =~ /(.*?)(\/[^\/]*)?$/) { + $args{base} = join('/',$1,$child); + } else { + $args{base} = $child; + } + + $args{view} = $this->view if $this->view; + $args{hash} = $this->hash if $this->hash; + + if (@_) { + my $query = shift; + + $args{query} = ref $query eq 'HASH' ? hashMerge($this->query,$query) : $query; + } + + return $this->new(%args); + +} + +sub Query { + my ($this,$query) = @_; + + my %args; + + $args{base} = $this->base; + $args{view} = $this->view if $this->view; + $args{hash} = $this->hash if $this->hash; + $args{query} = ref $query eq 'HASH' ? hashMerge($this->query,$query) : $query; + + return $this->new(%args); +} + +sub SetView { + my ($this,$newView) = @_; + + $this->view($newView); + + return $this; +} + +sub url { + my ($this) = @_; + + my $url = URI->new($this->view ? $this->base . "." . $this->view : $this->base); + $url->query_form($this->query); + $url->fragment($this->hash); + + return $url; +} + +sub ToAbsolute { + my ($this,$baseUrl) = @_; + + return URI->new_abs( $this->url, $baseUrl ); +} + +sub toString { + shift->url->as_string(); +} + +sub AUTOLOAD { + our $AUTOLOAD; + + (my $method) = ($AUTOLOAD =~ m/(\w+)$/); + + return if $method eq 'DESTROY'; + + my $this = shift; + return $this->Child($method,@_); +} + + + +1; + +__END__ + +=head1 NAME + +C<IMPL::Web::AutoLocator> - Обертка вокруг адреса ресурса. + +=head1 SYNOPSIS + +=begin code + +use IMPL::require { + Locator => 'IMPL::Web::AutoLocator' +}; + +my $bugTracker = Locator->new(base => "http://myhost.org/bugzilla")->SetView("cgi"); + +my $bug = $bugTracker->show_bug({id = 1}); + +my $wikiPages = Locator->new(base => "http://myhost.org/wiki/bin/view"); + +my $page = $wiki->Main->HowTo; + +my $images = Locator->new(base => "http://static.myhost.org/images", view => "png"); + +my $editIco = $images->icons->small->edit; + +=end code + +=head1 DESCRIPTION + +Для удобстав навигации по ресурсам, полностью отражает классическую структуру +иерархически организованных ресурсов. позволяет гибко работать с параметрами +запроса и хешем. Для постоты чтения реализует метод C<AUTOLOAD> для доступа +к дочерним ресурсам. + +=head1 MEMBERS + +=head2 C<CTOR(%args)> + +Создает новый объект расположение. Позволяет задать путь, расширение, параметры +запроса и фрагмент ресурса. + +=over + +=item * C<base> + +Строка с базовым адресом для дочерних ресурсов. + +=item * C<view> + +Задает суфикс, обозначающий представление ресурса, аналогично расширению у +файлов. Данный суффикс может использоваться контроллером для выбора +представления ресурса. + +=item * C<query> + +Ссылка на хеш с параметрами запроса + +=item * C<hash> + +Часть C<uri> обозначающая фрагмент документа (все, что идет после символа C<#>). + +=back + +=head2 C<Child($child[,$query])> + +Получает расположение дочернего ресурса. При этом cоздается новый объект адреса ресурса. + +=head2 C<SetView($view)> + +Позволяет указать представление (расширение) у текущего адреса ресурса. Изменяет +представление и возвращает измененный адрес ресурса. + +=head2 C<[get]base> + +Базовый адрес, относительно которого будут получены дочерние ресурсы. + +=head2 C<[get,set]view> + +Представление для ресурсов, аналогично расширению у файлов. + +=head2 C<[get,set]query> + +Ссылка на хеш с параметрами для C<GET> запроса. + +=head2 C<[get,set]hash> + +Часть адреса ресурса, отвечающая за фрагмент. + +=head2 C<[get]url> + +Объект C<URI> для текущего адреса. + +=head2 C<AUTLOAD> + +Перенаправляет вызовы методов в метод C<Child> передавая первым параметром имя метода. + +=cut +