diff Lib/IMPL/Web/Application/ResourceContract.pm @ 228:431db7034a88

Для синхронизации
author andrei <andrei@nap21.upri>
date Thu, 13 Sep 2012 17:55:01 +0400
parents 70ad6bc20908
children 47f77e6409f7
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/ResourceContract.pm	Fri Sep 07 16:32:17 2012 +0400
+++ b/Lib/IMPL/Web/Application/ResourceContract.pm	Thu Sep 13 17:55:01 2012 +0400
@@ -3,6 +3,9 @@
 use IMPL::lang qw(:declare);
 use IMPL::declare {
 	require => {
+		'Exception' => 'IMPL::Exception',
+		'ArgumentException' => '-IMPL::ArgumentException',
+		'KeyNotFoundException' => '-IMPL::KeyNotFoundException',
 		'ResourceClass' => 'IMPL::Web::Application::Resource'
 	},
 	base => [
@@ -14,7 +17,7 @@
 	public property resourceFactory => PROP_ALL;
 	public property operations => PROP_ALL;
 	private property _namedResources => PROP_ALL;
-	private property _regexpResources => PROP_ALL; 
+	private property _regexpResources => PROP_ALL | PROP_LIST; 
 }
 
 sub CTOR {
@@ -22,10 +25,90 @@
 	my %args = @_;
 	
 	$this->resourceFactory( $args{resourceFactory} || ResourceClass );
+	
+	my $resources = $args{resources} || [];
+	my $operations = $args{operations} || {};
+	
+	die ArgumentException->new(resources => 'resources parameter must be a reference to an array')
+	   unless ref $resources eq 'ARRAY';
+	   
+	die ArgumentException->new(opearations => 'operations parameter must be a reference to a hash')
+	   unless ref $operations eq 'HASH';
+	   
+	my %nameMap;
+		   
+	foreach my $res (@$resources) {
+		next unless $res->{contract};
+		if(my $name = $res->{name}) {
+			$nameMap{$name} = $res;
+		}
+		if($res->{match}) {
+			$this->_regexpResources->Append($res);
+		}
+	}
+	
+	$this->_namedResources(\%nameMap);
 }
 
 sub CreateResource {
-	my ($this,)
+	my $this = shift;
+	my %args = @_;
+	
+	return $this->resourceFactory->new (
+	   %args,
+	   contract => $this
+	);
+}
+
+sub FindChildResourceContractInfo {
+	my ($this,$name) = @_;
+	
+	if(my $contract = $this->_namedResources->{$name}) {
+		return $contract;
+	} else {
+		foreach my $info ( $this->_regexpResources ) {
+			my $rx = $info->{match};
+			return $info if $name =~ m/$rx/;
+		}
+	}
+	
+	return undef;
+}
+
+sub CreateChildResource {
+	my $this = @_;
+	my %args = @_;
+	
+	my $id = $args{id} or die ArgumentException( id => 'id parameter must be specified');
+	my $parent = $args{parent};
+	my $model = $parent->model if $parent;
+	my $binding, $childContract, @bindingVars;
+	
+	if(my $info = $this->_namedResources->{$id}) {
+		@bindingVars = ($id);
+		$childContract = $info->{contract};
+		$binding = $info->{bind};
+    } else {
+        foreach my $info ( $this->_regexpResources ) {
+            my $rx = $info->{match};
+            next unless $rx;
+            if( @bindingVars = ($id =~ m/$rx/) ) {
+            	$childContract = $info->{contract};
+            	$binding = $info->{bind};
+            }
+        }
+    }
+    
+    if ($childContract) {
+    	my $childModel = $binding ? $binding->($parent,$model,@bindingVars) : undef;
+    	
+    	return $childContract->CreateResource(
+    	   %args,
+    	   model => $childModel
+    	);
+    } else {
+    	die KeyNotFoundException->new($id);
+    }
 }
 
 1;
@@ -81,6 +164,11 @@
     id => 'item-something'
 );
 
+my $child = $contract->CreateChildResource(
+    parent => $resource,
+    id => 'info'
+);
+
 =end code 
 
 =head1 DESCRIPTION