diff Lib/IMPL/Web/Application/CustomResource.pm @ 334:71221d79e6b4

removing web resources contracts
author cin
date Thu, 13 Jun 2013 02:24:57 +0400
parents 04a093f0a5a6
children e8be9062ecf2
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/CustomResource.pm	Tue Jun 11 20:22:52 2013 +0400
+++ b/Lib/IMPL/Web/Application/CustomResource.pm	Thu Jun 13 02:24:57 2013 +0400
@@ -5,8 +5,8 @@
 
 use IMPL::declare {
     require => {
-        Factory => 'IMPL::Object::Factory',
-        CustomResourceContract => 'IMPL::Web::Application::CustomResourceContract'        
+        NotAllowedException => 'IMPL::Web::NotAllowedException',
+        HttpResponse => 'IMPL::Web::HttpResponse'
     },
     base => [
         'IMPL::Web::Application::Resource' => '@_'
@@ -16,49 +16,79 @@
     ]
 };
 
-__PACKAGE__->static_accessor(contractFactory => CustomResourceContract );
-__PACKAGE__->static_accessor_own(_contractInstance => undef);
+our %RESOURCE_BINDINGS = (
+    GET => 'HttpGet',
+    POST => 'HttpPost',
+    PUT => 'HttpPut',
+    DELETE => 'HttpDelete',
+    HEAD => 'HttpHead'
+);
+
+__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->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)));
+            }
+        }
+    }
 }
 
-sub contractInstance {
-    my ($self) = @_;
+sub FindChildResourceInfo {
+    my ( $this, $name ) = @_;
     
-    $self = ref $self || $self;
-    $self->_contractInstance ? $self->_contractInstance : $self->InitContract();
+    $this->_PrepareResourcesCache()
+        unless($this->_nameResourcesMap);
+        
+    return $this->next::method($name);
 }
 
-sub InitContract {
-    my ($self) = @_;
-    $self->_contractInstance(
-        $self->contractFactory->new(
-            resourceFactory => $self,
-            resources => [ $self->GetChildResources() ]
-        )
-    ); 
+sub PrepareResourcesCache {
+    # suppress default caching mechanisn
 }
 
-sub CreateContract {
-    my ($self, %args) = @_;
-    
-    $self->contractFactory->new(
-        resourceFactory => Factory->new(
-            $self,
-            \%args
-        ),
-        resources => [ $self->GetChildResources() ]
-    )
-}
+sub _PrepareResourcesCache {
+    # a little bit wired
+    my ($self) = @_;
+    my %nameMap;
+    my @rxMap;
 
-sub CreateResource {
-    my ($self,%args) = @_;
-    
-    $self->CreateContract()->CreateResource(%args);
+    foreach my $res ($self->GetChildResources()) {
+        #skip resources without contract
+        next unless $res->{contract};
+        
+        if ( my $name = $res->{name} ) {
+            $nameMap{$name} = $res;
+        }
+        if ( $res->{match} ) {
+            push @rxMap,$res;
+        }
+    }
+
+    $self->_rxResourcesMap(\@rxMap);
+    $self->_nameResourcesMap(\%nameMap);
 }
 
 sub AccessCheck {
@@ -67,7 +97,7 @@
 	my $handler = $this->accessCheck; 
 	
 	if(ref($handler) eq 'CODE') {
-		&$handler($this,$verb);
+		return &$handler($this,$verb);
 	}
 }
 
@@ -75,6 +105,23 @@
     
 }
 
+sub _HttpOptionsBinding {
+    my ($this) = @_;
+    
+    my @allow = $this->_GetAllowedHttpMethods();
+    return HttpResponse->new(
+        status => '200 OK',
+        headers => {
+            allow => join ( ',', @allow )
+        }
+    );
+}
+
+sub _GetAllowedHttpMethods {
+    my ($this) = @_;
+    return grep $this->can($RESOURCE_BINDINGS{$_}), keys %RESOURCE_BINDINGS;
+}
+
 
 1;
 
@@ -111,18 +158,22 @@
     $this->model->update( $form->Bind($action) );
 }
 
-our %COMPONENTS = (
-	item => {
-		verbs => {
-			get => sub {
-				shift->model;
-			}
-		},
-		resources => [
-			edit => 
-		]
-	}
-);
+sub GetChildResources {
+    return {
+        name => 'create',
+        contract => {
+            class => 'My::Web::FormResource',
+            formName => 'create',
+            schema => 'profile.schema'
+        }
+    },
+    {
+        match => qr/^(.*)$/,
+        contract => {
+            class => 'My::Web::ItemResource'
+        }
+    }
+}
 
 =end code