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
+