changeset 335:e8be9062ecf2

improved resource classes, contracts are deprecated
author cin
date Thu, 13 Jun 2013 20:13:24 +0400
parents 71221d79e6b4
children 86336d451b82
files Lib/IMPL/Web/Application/CustomResource.pm Lib/IMPL/Web/Application/Resource.pm
diffstat 2 files changed, 55 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/CustomResource.pm	Thu Jun 13 02:24:57 2013 +0400
+++ b/Lib/IMPL/Web/Application/CustomResource.pm	Thu Jun 13 20:13:24 2013 +0400
@@ -12,7 +12,11 @@
         'IMPL::Web::Application::Resource' => '@_'
     ],
     props => [
-        accessCheck => PROP_RW
+        accessCheck => PROP_RW,
+        resources   => PROP_RO,
+        verbs       => PROP_RO,
+        namedResources => PROP_RO,
+        regexResources => PROP_RO
     ]
 };
 
@@ -21,61 +25,61 @@
     POST => 'HttpPost',
     PUT => 'HttpPut',
     DELETE => 'HttpDelete',
-    HEAD => 'HttpHead'
+    HEAD => 'HttpHead',
+    OPTIONS => 'HttpOptions',
+    TRACE => 'HttpTrace'
 );
 
-__PACKAGE__->static_accessor(_rxResourcesMap => undef, 'own');
-__PACKAGE__->static_accessor(_nameResourcesMap => undef, 'own');
-
-sub namedResources {
-    shift->_nameResourcesMap;
-}
-
-sub regexResources {
-    shift->_rxResourcesMap;
-}
-
 sub CTOR {
 	my ($this,%args) = @_;
 	
+	$this->verbs($args{verbs} || {});
+	$this->resources($args{resources} || []);
+	
 	$this->accessCheck($args{accessCheck})
 	   if $args{accessCheck};
 	   
-	$this->verbs->{options} ||= \&_HttpOptionsBinding;
-    
     while(my ($verb,$methodName) = each %RESOURCE_BINDINGS) {
-        $this->verbs->{lc($verb)} ||= sub {
-            my ($resource,$action) = @_;
-   
-            if (eval { $resource->can($methodName) }) {
-                return $resource->$methodName($action);
-            } else {
-                die NotAllowedException->new(allow => join(',', _GetAllowedHttpMethods($resource)));
-            }
-        }
+    	if(my $method = $this->can($methodName)) {
+    		$this->verbs->{lc($verb)} ||= $method;
+    	}
     }
 }
 
 sub FindChildResourceInfo {
     my ( $this, $name ) = @_;
     
-    $this->_PrepareResourcesCache()
-        unless($this->_nameResourcesMap);
-        
-    return $this->next::method($name);
+    $this->PrepareResourcesCache()
+        unless $this->namedResources;
+    
+    if ( my $info = $this->namedResources->{$name} ) {
+        return $info, [$name];
+    }
+    else {
+        foreach my $info ( @{$this->regexResources} ) {
+            my $rx = $info->{match};
+            if(my @childId = $name =~ m/$rx/) {
+                return $info, \@childId; 
+            }
+        }
+    }
+
+    return;
+}
+
+sub GetAllowedMethods {
+    map( uc, keys %{ shift->verbs } );
 }
 
 sub PrepareResourcesCache {
-    # suppress default caching mechanisn
-}
-
-sub _PrepareResourcesCache {
-    # a little bit wired
-    my ($self) = @_;
+    my ($this) = @_;
+    
+    my @resources = ($this->GetChildResources(), @{$this->resources});
+    
     my %nameMap;
     my @rxMap;
 
-    foreach my $res ($self->GetChildResources()) {
+    foreach my $res (@resources) {
         #skip resources without contract
         next unless $res->{contract};
         
@@ -87,8 +91,8 @@
         }
     }
 
-    $self->_rxResourcesMap(\@rxMap);
-    $self->_nameResourcesMap(\%nameMap);
+    $this->regexResources(\@rxMap);
+    $this->namedResources(\%nameMap);
 }
 
 sub AccessCheck {
@@ -105,10 +109,10 @@
     
 }
 
-sub _HttpOptionsBinding {
+sub HttpOptions {
     my ($this) = @_;
     
-    my @allow = $this->_GetAllowedHttpMethods();
+    my @allow = $this->GetAllowedMethods();
     return HttpResponse->new(
         status => '200 OK',
         headers => {
@@ -117,12 +121,6 @@
     );
 }
 
-sub _GetAllowedHttpMethods {
-    my ($this) = @_;
-    return grep $this->can($RESOURCE_BINDINGS{$_}), keys %RESOURCE_BINDINGS;
-}
-
-
 1;
 
 __END__
--- a/Lib/IMPL/Web/Application/Resource.pm	Thu Jun 13 02:24:57 2013 +0400
+++ b/Lib/IMPL/Web/Application/Resource.pm	Thu Jun 13 20:13:24 2013 +0400
@@ -13,7 +13,8 @@
 		OperationException  => '-IMPL::InvalidOperationException',
 		NotAllowedException => 'IMPL::Web::NotAllowedException',
 		NotFoundException   => 'IMPL::Web::NotFoundException',
-		Loader              => 'IMPL::Code::Loader' 
+		Loader              => 'IMPL::Code::Loader',
+		CustomResource      => '-IMPL::Web::Application::CustomResource' 
 	  },
 	  base => [
 		'IMPL::Object'                              => undef,
@@ -26,10 +27,6 @@
 		model       => PROP_RO,
 		id          => PROP_RO,
 		location    => PROP_RO,
-		resources   => PROP_RO,
-		verbs       => PROP_RO,
-		namedResources => PROP_RO,
-		regexResources => PROP_RO
 	  ]
 };
 
@@ -48,45 +45,20 @@
 	$this->model( $args{model} );
 	$this->id( $args{id} );
 	$this->application( $args{request}->application );
-	$this->verbs( $args{verbs} || {} );
-	$this->resources($args{resources} || []);
 	
-	$this->PrepareResourcesCache();
-
 # если расположение явно не указано, то оно вычисляется автоматически,
 # либо остается не заданным
 	$this->location( $args{location}
 		  || eval { $this->parent->location->Child( $this->id ) } );
 }
 
-sub PrepareResourcesCache {
-    my ($this,$resources) = @_;
-    my %nameMap;
-    my @rxMap;
-
-    foreach my $res (@{$this->resources}) {
-        #skip resources without contract
-        next unless $res->{contract};
-        
-        if ( my $name = $res->{name} ) {
-            $nameMap{$name} = $res;
-        }
-        if ( $res->{match} ) {
-            push @rxMap,$res;
-        }
-    }
-
-    $this->regexResources(\@rxMap);
-    $this->namedResources(\%nameMap);
-}
-
 sub InvokeHttpVerb {
 	my ( $this, $verb ) = @_;
 
 	my $operation = $this->verbs->{ lc($verb) };
 
 	die NotAllowedException->new(
-		allow => join( ',', map( uc, keys %{ $this->verbs } ) ) )
+		allow => join( ',', $this->GetAllowedMethods ) )
 	  unless $operation;
 
 	$this->AccessCheck($verb);
@@ -110,6 +82,14 @@
 	return _InvokeDelegate( $operation, $this, $request );
 }
 
+sub GetAllowedMethods {
+	
+}
+
+sub FindChildResourceInfo {
+	
+}
+
 sub AccessCheck {
 
 }
@@ -129,24 +109,6 @@
 	return $env;
 }
 
-sub FindChildResourceInfo {
-    my ( $this, $name ) = @_;
-    
-    if ( my $info = $this->namedResources->{$name} ) {
-        return $info, [$name];
-    }
-    else {
-        foreach my $info ( @{$this->regexResources} ) {
-            my $rx = $info->{match};
-            if(my @childId = $name =~ m/$rx/) {
-                return $info, \@childId; 
-            }
-        }
-    }
-
-    return;
-}
-
 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся
 # в контракте.
 sub FetchChildResource {
@@ -186,7 +148,7 @@
 	my $factory;
 	
 	if (ref($contract) eq 'HASH') {
-	    $factory = delete $contract->{class} || __PACKAGE__;
+	    $factory = delete $contract->{class} || CustomResource;
 	    hashApply(\%args,$contract);
 	    
 	    Loader->default->Require($factory)