changeset 113:7b14e0122b79

Updated PostToDOM transformation added selectSingleNode method to IMPL::DOM::Node Implemented FormWrapper in the Web::Application::ControllerUnit
author wizard
date Fri, 21 May 2010 02:38:11 +0400
parents 0ed8e2541b1c
children 7084af955c57
files Lib/IMPL/DOM/Navigator/Builder.pm Lib/IMPL/DOM/Node.pm Lib/IMPL/DOM/Transform/PostToDOM.pm Lib/IMPL/DOM/XMLReader.pm Lib/IMPL/Web/Application/ControllerUnit.pm
diffstat 5 files changed, 107 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Navigator/Builder.pm	Tue May 18 17:59:31 2010 +0400
+++ b/Lib/IMPL/DOM/Navigator/Builder.pm	Fri May 21 02:38:11 2010 +0400
@@ -84,6 +84,8 @@
 sub inflateValue {
 	my ($this,$value,$node) = @_;
 	
+	$node ||= $this->Current;
+	
 	my $nodeSchema = $this->{$_schemaNavi}->Current;
 	
 	my $result = eval { $nodeSchema->inflateValue($value) };
--- a/Lib/IMPL/DOM/Node.pm	Tue May 18 17:59:31 2010 +0400
+++ b/Lib/IMPL/DOM/Node.pm	Fri May 21 02:38:11 2010 +0400
@@ -202,6 +202,12 @@
 	return wantarray ? @set : \@set;   
 }
 
+sub selectSingleNode {
+	my $this = shift;
+	my @result = $this->selectNodes(@_);
+	return $result[0];
+}
+
 sub selectNodesRef {
 	my $this = shift;
 	
--- a/Lib/IMPL/DOM/Transform/PostToDOM.pm	Tue May 18 17:59:31 2010 +0400
+++ b/Lib/IMPL/DOM/Transform/PostToDOM.pm	Fri May 21 02:38:11 2010 +0400
@@ -10,17 +10,22 @@
 BEGIN {
     public property documentClass => prop_get | owner_set;
     public property documentSchema => prop_get | owner_set;
+    public property prefix => prop_get | owner_set;
     private property _navi => prop_all;
+    public property Errors => prop_all | prop_list;
+    private property _schema => prop_all;
 }
 
 our %CTOR = (
     'IMPL::Transform' => sub {
-        HASH => \&TransfromPostData
+    	-plain => \&TransformPlain,
+        HASH => \&TransformContainer,
+        CGI => \&TransformCGI
     }
 );
 
 sub CTOR {
-	my ($this,$docClass,$docSchema) = @_;
+	my ($this,$docClass,$docSchema,$prefix) = @_;
 	$docClass ||= 'IMPL::DOM::Document';
 	
 	$this->_navi(
@@ -29,30 +34,60 @@
 			$docSchema
 		)
 	);
+	$this->_schema($docSchema);
+	$this->prefix($prefix) if $prefix;
 }
 
-sub TransformPostData {
+sub TransformContainer {
     my ($this,$data) = @_;
     
     my $navi = $this->_navi;
-    
-    my %
-    
+        
     while (my ($key,$value) = each %$data) {
-    	# TODO: review
-    	$navi->save;
-        my $node = $navi->Navigate(split /\//, $key);
-        $node->nodeValue($value);
-        $navi->resore;
+    	
+    	$navi->NavigateCreate($key);
+    	
+    	$this->Transform($value);
+    	
+    	$navi->Back();
     }
     
-    return $navi->Document;
+    return $navi->Current;
+}
+
+sub TransformPlain {
+	my ($this,$data) = @_;
+	
+	$this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) );
 }
 
-sub 
-
-sub TransformErrors {
-	return $_[0]->_navi->BuildErrors;
+sub TransformCGI {
+	my ($this,$query) = @_;
+	
+	my $data={};
+	
+	my $prefix = $this->prefix;
+	$prefix = qr/$prefix/;
+	
+	foreach my $param (grep $_=~/$prefix/, $query->param()) {
+		my $value = $query->param($param);
+		
+		my @parts = split /\//,$param;
+		
+		my $node = $data;
+		while ( my $part = shift @parts ) {
+			if (@parts) {
+				$node = ($node->{$part} ||= {});
+			} else {			
+				$node->{$part} = $value;
+			}
+		}  
+	}
+	
+	my $doc = $this->Transform($data);
+	$this->Errors->Append( $this->_navi->BuildErrors);
+	$this->Errors->Append( $this->_schema->Validate($doc));
+	return $doc;
 }
 
 1;
--- a/Lib/IMPL/DOM/XMLReader.pm	Tue May 18 17:59:31 2010 +0400
+++ b/Lib/IMPL/DOM/XMLReader.pm	Fri May 21 02:38:11 2010 +0400
@@ -57,7 +57,7 @@
 
 sub _OnEnd {
     my ($this,$element) = @_;
-    $this->{$_current}->nodeValue($this->Navigator->inflateValue( $this->{$_text}, $this->{$_current} ) ) if length $this->{$_text};
+    $this->{$_current}->nodeValue($this->Navigator->inflateValue( $this->{$_text} ) ) if length $this->{$_text};
     $this->{$_text} = pop @{$this->{$_textHistory}};
     $this->{$_current} = $this->Navigator->Back;
 }
--- a/Lib/IMPL/Web/Application/ControllerUnit.pm	Tue May 18 17:59:31 2010 +0400
+++ b/Lib/IMPL/Web/Application/ControllerUnit.pm	Fri May 21 02:38:11 2010 +0400
@@ -5,6 +5,8 @@
 use IMPL::Class::Property;
 use IMPL::DOM::Transform::PostToDOM;
 use IMPL::DOM::Schema;
+use Class::Inspector;
+use File::Spec;
 
 use constant {
 	CONTROLLER_METHODS => 'controller_methods',
@@ -22,6 +24,8 @@
 	public property formErrors => prop_get | owner_set;
 }
 
+__PACKAGE__->class_data(CONTROLLER_METHODS,{});
+
 sub CTOR {
 	my ($this,$action,$args) = @_;
 	
@@ -56,7 +60,9 @@
 }
 
 sub transactions {
+	my ($self,@names) = @_;
 	
+	$self->class_data(CONTROLLER_METHODS)->{$_} = {} foreach @names;
 }
 
 sub InvokeAction {
@@ -81,17 +87,49 @@
 }
 
 sub FormWrapper {
-	my ($this,$method,$action,$methodInfo) = @_;
+	my ($self,$method,$action,$methodInfo) = @_;
+	
+	my $schema = $self->loadSchema($methodInfo->{schema});
+	
+	my $process = $action->query->param('process') || 0;
+	my $form = $methodInfo->{form}
+		|| $action->query->param('form')
+		|| $schema->selectSingleNode('ComplexNode')->name
+			or die new IMPL::Exception('No situable form name could be determined',$self,$method);
 	
-	my $schema = $this->loadSchema($methodInfo->{schema});
+	my %result;
 	
-	my $process = $this->query->param('process') || 0;
+	my $transform = IMPL::DOM::Transform::PostToDOM->new(
+		undef,
+		$schema,
+		$form
+	);
+	
+	$result{formSchema} = $schema;
+	$result{formData} = $transform->Transform($self->query);
 	
-	
+	if ($process) {
+		$result{formErrors} = $transform->Errors->as_list;
+		if ($transform->Errors->Count) {
+			$result{state} = STATE_INVALID;
+		} else {
+			$result{state} = STATE_CORRECT;
+			my $unit = $self->new($action,\%result);
+			$result{result} = $unit->method();
+		}
+	} else {
+		$result{state} = STATE_NEW;
+	}
 	
-	my %result = (
-		
-	);
+	return \%result;
+}
+
+sub loadSchema {
+	my ($self,$name) = @_;
+
+	my ($vol,$dir,$file) = File::Spec->splitpath( Class::Inspector->resolved_filename(ref $self || $self) );
+	
+	return IMPL::DOM::Schema->LoadSchema(File::Spec->catfile($vol,$dir,$name));
 }
 
 1;
@@ -106,9 +144,8 @@
 
 =head1 DESCRIPTION
 
-Классы, наследуемые от данного класса используются для выполнения транзакций, которые приходят
-через контроллер запросов. Как правило один класс представляет собой пакет транзакций, каждая
-из которых является независимой от другой.
+Классы, наследуемые от данного класса называется пакетом транзакций. Часть методов в таком классе
+объявляются как транзакции при помощи методов C<transaction>, C<form>.
 
 Перед выполнением транзакции создается экземпляр объекта, в рамках которого будет выполнена транзакция.
 Для этого вызывается метод C<InvokeAction($method,$action)>, который создает/восстанавливает контекст