annotate Lib/IMPL/Web/Application/ControllerUnit.pm @ 144:b56ebc31bf18

Empty nodes no more created while transforming a post request to the DOM document minor speed improvements to the object CTOR caching Added support for a secure processing (and 'laundering' ) a CGI parameters Many minor fixes
author wizard
date Tue, 13 Jul 2010 02:05:38 +0400
parents 4c9849f0f879
children 60fd224f3e3c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
1 use strict;
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
2 package IMPL::Web::Application::ControllerUnit;
c13a215508ca Refactoring,
wizard
parents:
diff changeset
3 use base qw(IMPL::Object);
c13a215508ca Refactoring,
wizard
parents:
diff changeset
4
c13a215508ca Refactoring,
wizard
parents:
diff changeset
5 use IMPL::Class::Property;
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
6 use IMPL::DOM::Transform::PostToDOM;
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
7 use IMPL::DOM::Schema;
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
8 use Class::Inspector;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
9 use File::Spec;
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
10 use Sub::Name;
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
11
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
12 use constant {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
13 CONTROLLER_METHODS => 'controller_methods',
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
14 STATE_CORRECT => 'correct',
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
15 STATE_NEW => 'new',
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
16 STATE_INVALID => 'invalid'
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
17 };
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
18
c13a215508ca Refactoring,
wizard
parents:
diff changeset
19 BEGIN {
c13a215508ca Refactoring,
wizard
parents:
diff changeset
20 public property action => prop_get | owner_set;
c13a215508ca Refactoring,
wizard
parents:
diff changeset
21 public property application => prop_get | owner_set;
c13a215508ca Refactoring,
wizard
parents:
diff changeset
22 public property query => prop_get | owner_set;
144
b56ebc31bf18 Empty nodes no more created while transforming a post request to the DOM document
wizard
parents: 142
diff changeset
23 public property response => prop_get | owner_set;
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
24 public property formData => prop_get | owner_set;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
25 public property formSchema => prop_get | owner_set;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
26 public property formErrors => prop_get | owner_set;
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
27 }
c13a215508ca Refactoring,
wizard
parents:
diff changeset
28
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
29 my %publicProps = map {$_->Name , 1} __PACKAGE__->get_meta(typeof IMPL::Class::PropertyInfo);
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
30
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
31 __PACKAGE__->class_data(CONTROLLER_METHODS,{});
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
32
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
33 sub CTOR {
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
34 my ($this,$action,$args) = @_;
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
35
c13a215508ca Refactoring,
wizard
parents:
diff changeset
36 $this->action($action);
c13a215508ca Refactoring,
wizard
parents:
diff changeset
37 $this->application($action->application);
c13a215508ca Refactoring,
wizard
parents:
diff changeset
38 $this->query($action->query);
144
b56ebc31bf18 Empty nodes no more created while transforming a post request to the DOM document
wizard
parents: 142
diff changeset
39 $this->response($action->response);
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
40
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
41 $this->$_($args->{$_}) foreach qw(formData formSchema formErrors);
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
42 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
43
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
44 sub unitNamespace() {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
45 ""
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
46 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
47
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
48 sub transactions {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
49 my ($self,%methods) = @_;
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
50
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
51 while (my ($method,$info) = each %methods) {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
52 if ($info and ref $info ne 'HASH') {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
53 warn "Bad transaction $method description";
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
54 $info = {};
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
55 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
56
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
57 $info->{wrapper} = 'TransactionWrapper';
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
58 $self->class_data(CONTROLLER_METHODS)->{$method} = $info;
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
59 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
60 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
61
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
62 sub forms {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
63 my ($self,%forms) = @_;
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
64
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
65 while ( my ($method,$info) = each %forms ) {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
66 die new IMPL::Exception("A method doesn't exists in the controller",$self,$method) unless $self->can($method);
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
67 if ( not ref $info ) {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
68 $self->class_data(CONTROLLER_METHODS)->{$method} = {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
69 wrapper => 'FormWrapper',
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
70 schema => $info
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
71 };
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
72 } elsif (ref $info eq 'HASH') {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
73 die new IMPL::Exception("A schema must be specified",$self,$method) unless $info->{schema};
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
74
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
75 $self->class_data(CONTROLLER_METHODS)->{$method} = {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
76 wrapper => 'FormWrapper',
142
4c9849f0f879 minor changes
wizard
parents: 138
diff changeset
77 schema => $info->{schema},
4c9849f0f879 minor changes
wizard
parents: 138
diff changeset
78 form => $info->{form}
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
79 };
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
80 } else {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
81 die new IMPL::Exception("Unsupported method information",$self,$method);
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
82 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
83 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
84 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
85
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
86 sub InvokeAction {
c13a215508ca Refactoring,
wizard
parents:
diff changeset
87 my ($self,$method,$action) = @_;
c13a215508ca Refactoring,
wizard
parents:
diff changeset
88
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
89 if (my $methodInfo = $self->class_data(CONTROLLER_METHODS)->{$method}) {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
90 if (my $wrapper = $methodInfo->{wrapper}) {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
91 return $self->$wrapper($method,$action,$methodInfo);
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
92 } else {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
93 return $self->TransactionWrapper($method,$action,$methodInfo);
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
94 }
110
c13a215508ca Refactoring,
wizard
parents:
diff changeset
95 } else {
c13a215508ca Refactoring,
wizard
parents:
diff changeset
96 die new IMPL::InvalidOperationException("Invalid method call",$self,$method);
c13a215508ca Refactoring,
wizard
parents:
diff changeset
97 }
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
98 }
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
99
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
100 sub MakeParams {
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
101 my ($this,$methodInfo) = @_;
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
102
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
103 my $params;
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
104 if ($params = $methodInfo->{parameters} and ref $params eq 'ARRAY') {
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
105 return map $this->ResolveParam($_), @$params;
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
106 }
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
107 return();
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
108 }
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
109
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
110 sub ResolveParam {
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
111 my ($this,$param) = @_;
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
112
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
113 if ( $param =~ /^::(\w+)$/ and $publicProps{$1}) {
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
114 return $this->$1();
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
115 } else {
144
b56ebc31bf18 Empty nodes no more created while transforming a post request to the DOM document
wizard
parents: 142
diff changeset
116 return scalar($this->query->param($param));
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
117 }
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
118 }
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
119
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
120 sub TransactionWrapper {
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
121 my ($self,$method,$action,$methodInfo) = @_;
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
122
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
123 my $unit = $self->new($action);
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
124 return $unit->$method($unit->MakeParams($methodInfo));
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
125 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
126
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
127 sub FormWrapper {
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
128 my ($self,$method,$action,$methodInfo) = @_;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
129
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
130 my $schema = $self->loadSchema($methodInfo->{schema});
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
131
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
132 my $process = $action->query->param('process') || 0;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
133 my $form = $methodInfo->{form}
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
134 || $action->query->param('form')
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
135 || $schema->selectSingleNode('ComplexNode')->name
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
136 or die new IMPL::Exception('No situable form name could be determined',$self,$method);
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
137
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
138 my %result;
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
139
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
140 my $transform = IMPL::DOM::Transform::PostToDOM->new(
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
141 undef,
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
142 $schema,
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
143 $form
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
144 );
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
145
138
c5bc900eefd3 IMPL::Web::Application: Fixed file uploading
wizard
parents: 134
diff changeset
146 $result{formName} = $form;
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
147 $result{formSchema} = $schema;
126
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
148 $result{formData} = $transform->Transform($action->query);
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
149
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
150
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
151 if ($process) {
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
152 $result{formErrors} = $transform->Errors->as_list;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
153 if ($transform->Errors->Count) {
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
154 $result{state} = STATE_INVALID;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
155 } else {
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
156 $result{state} = STATE_CORRECT;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
157 my $unit = $self->new($action,\%result);
127
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
158
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
159 eval {
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
160 $result{result} = $unit->$method($unit->MakeParams($methodInfo));
127
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
161 };
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
162 if (my $err = $@) {
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
163 $result{state} = STATE_INVALID;
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
164 if (eval { $err->isa(typeof IMPL::WrongDataException) } ) {
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
165 $result{formErrors} = $err->Args;
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
166 } else {
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
167 die $err;
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
168 }
0dce0470a3d8 In the IMPL::Web::ControllerUnit added the ability to notify a form about a wrong data from a transaction
wizard
parents: 126
diff changeset
169 }
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
170 }
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
171 } else {
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
172 $result{state} = STATE_NEW;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
173 }
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
174
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
175 return \%result;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
176 }
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
177
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
178 sub loadSchema {
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
179 my ($self,$name) = @_;
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
180
126
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
181 if (-f $name) {
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
182 return IMPL::DOM::Schema->LoadSchema($name);
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
183 } else {
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
184 my ($vol,$dir,$file) = File::Spec->splitpath( Class::Inspector->resolved_filename(ref $self || $self) );
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
185
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
186 return IMPL::DOM::Schema->LoadSchema(File::Spec->catfile($vol,$dir,$name));
c8dfbbdd8005 Several bug fixes
wizard
parents: 113
diff changeset
187 }
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
188 }
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
189
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
190 sub discover {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
191 my ($this) = @_;
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
192
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
193 my $methods = $this->class_data(CONTROLLER_METHODS);
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
194
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
195 my $namespace = $this->unitNamespace;
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
196 (my $module = typeof $this) =~ s/^$namespace//;
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
197
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
198 my %smd = (
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
199 module => [grep $_, split /::/, $module ],
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
200 );
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
201
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
202 while (my ($method,$info) = each %$methods) {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
203 my %methodInfo = (
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
204 name => $method
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
205 );
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
206 $methodInfo{parameters} = $info->{parameters} if $info->{parameters};
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
207 push @{$smd{methods}},\%methodInfo;
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
208 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
209 return \%smd;
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
210 }
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
211
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
212 __PACKAGE__->transactions(
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
213 discover => undef
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
214 );
133
a07a66fd8d5c Added IMPL::Class::MethodInfo
wizard
parents: 132
diff changeset
215
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
216 1;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
217
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
218 __END__
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
219
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
220 =pod
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
221
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
222 =head1 NAME
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
223
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
224 C<IMPL::Web::Application::ControllerUnit> - базовый класс для обработчика транзакций в модели контроллера.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
225
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
226 =head1 DESCRIPTION
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
227
113
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
228 Классы, наследуемые от данного класса называется пакетом транзакций. Часть методов в таком классе
7b14e0122b79 Updated PostToDOM transformation
wizard
parents: 112
diff changeset
229 объявляются как транзакции при помощи методов C<transaction>, C<form>.
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
230
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
231 Перед выполнением транзакции создается экземпляр объекта, в рамках которого будет выполнена транзакция.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
232 Для этого вызывается метод C<InvokeAction($method,$action)>, который создает/восстанавливает контекст
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
233 транзакции.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
234
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
235 Транзакции на данный момент делятся на простые и формы. Различные типы транзакций выполняются при помощи
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
236 различных оберток (C<TransactionWrapper> и C<FormWrapper>). Каждая обертка отвечает за конструирование
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
237 экземпляра объекта и вызов метода для выполнения транзакции, а также за возврат результата выполнения.
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
238
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
239 =head2 Простые транзакции
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
240
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
241 Простые транзакции получаю только запрос, без предварительной обработки, и возвращенный результат напрямую
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
242 передается пользователю.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
243
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
244 =head2 Формы
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
245
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
246 При использовании форм запрос предварительно обрабатывается, для получения DOM документа с данными формы.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
247 Для постороенния DOM документа используется схема. При этом становятся доступны дополнительные свойства
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
248 C<formData>, C<formSchema>, C<formErrors>.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
249
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
250 Результат выполнения транзакции не возвращается наверх напрямую, а включается в структуру, которая
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
251 выглядит следующим образом
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
252
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
253 =begin code
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
254
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
255 {
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
256 state => '{ new | correct | invalid }',
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
257 result => $transactionResult,
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
258 formData => $formDOM,
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
259 formSchema => $formSchema,
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
260 formErrors => @errors
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
261 }
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
262
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
263 =end code
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
264
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
265 =over
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
266
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
267 =item C<state>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
268
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
269 Состояние верификации формы.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
270
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
271 =over
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
272
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
273 =item C<new>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
274
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
275 Первоначальное содержимое формы, оно может быть некорректным, но это нормально.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
276 В данном состоянии транзакция обычно не выполняется.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
277
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
278 =item C<correct>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
279
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
280 Данные формы корректны, транзакция выполнена, и ее результат доступен через поле C<result>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
281
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
282 =item C<invalid>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
283
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
284 Содержимое формы не прошло верификацию, ошибки доступны через поле C<formErrors>. Транзакция
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
285 не выполнялась.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
286
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
287 =back
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
288
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
289 =item C<result>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
290
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
291 Результат выполнения транзакции, если конечно таковая выполнялась.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
292
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
293 =item C<formData>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
294
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
295 ДОМ документ с данными формами. Документ существует всегда, не зависимо от его корректности,
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
296 может быть использован для построения формы, уже заполненную параметрами.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
297
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
298 =item C<formSchema>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
299
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
300 Схема данных формы, может использоваться для построения динамических форм.
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
301
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
302 =item C<formErrors>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
303
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
304 Ссылка на массив с ошибками при проверки формы.
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
305
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
306 =back
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
307
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
308 =head1 MEMBERS
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
309
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
310 =over
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
311
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
312 =item C<[get] application>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
313
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
314 Объект приложения, которое обрабатывает запрос.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
315
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
316 =item C<[get] query>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
317
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
318 Текущий запрос.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
319
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
320 =item C<[get] response>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
321
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
322 Текущий ответ.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
323
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
324 =item C<[get] formData>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
325
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
326 C<IMPL::DOM::Document> документ с данныим, если данный запрос является формой.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
327
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
328 =item C<[get] formSchema>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
329
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
330 C<IMPL::DOM::Schema> документ со схемой формы данного запроса.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
331
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
332 =item C<[get] formErrors>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
333
128
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
334 Ошибки верификации данных, если таковые были. Обычно при наличии ошибок в форме, транзакция
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
335 не выполняется, а эти ошибки передаются в ответ.
08753833173d Fixed a error handling issue in JSON output: errors are correctly transfered
wizard
parents: 127
diff changeset
336
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
337 =item C<InvokeAction($method,$action)>
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
338
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
339 Конструирует контекст выполнения транзакции, может быть переопределен для конструирования контекста по
112
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
340 своим правилам.
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
341
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
342 =item C<TransactionWrapper($method,$action,$methodInfo)>
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
343
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
344 Обертка для конструирования простых транзакций, может быть переопределен для конструирования контекста по
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
345 своим правилам.
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
346
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
347 =item C<FormWrapper($method,$action,$methodInfo)>
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
348
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
349 Обертка для конструирования форм, может быть переопределен для конструирования контекста по
0ed8e2541b1c Form processing mechanism
wizard
parents: 111
diff changeset
350 своим правилам.
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
351
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
352 =item C<discover()>
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
353
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
354 Метод, опубликованный для вызова контроллером, возвращает описание методов в формате C<Simple Module Definition>.
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
355
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
356 =begin code
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
357
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
358 # SMD structure
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
359 {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
360 module => ['Foo','Bar'],
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
361 methods => [
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
362 {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
363 name => 'search',
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
364 parameters => ['text','limit'] #optional
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
365 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
366 ]
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
367 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
368
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
369 =end code
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
370
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
371 =back
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
372
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
373 =head1 EXAMPLE
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
374
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
375 =begin code
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
376
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
377 package MyBooksUnit;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
378 use strict;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
379 use base qw(IMPL::Web::Application::ControllerUnit);
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
380
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
381 __PACKAGE__->PassThroughArgs;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
382
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
383 sub unitDataClass { 'My::Books' }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
384
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
385 __PACKAGE__->transactions(
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
386 find => {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
387 parameters => [qw(author)]
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
388 },
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
389 info => {
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
390 parameters => [qw(id)]
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
391 }
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
392 );
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
393 __PACKAGE__->forms(
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
394 create => 'books.create.xml'
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
395 );
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
396
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
397 sub find {
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
398 my ($this,$author) = @_;
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
399
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
400 return $this->ds->find({author => $author});
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
401 }
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
402
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
403 sub info {
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
404 my ($this,$id) = @_;
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
405
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
406 return $this->ds->find({id => $id});
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
407 }
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
408
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
409 sub create {
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
410 my ($this) = @_;
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
411
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
412 my %book = map {
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
413 $_->nodeName, $_->nodeValue
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
414 } $this->formData->selectNodes([qw(author_id title year ISBN)]);
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
415
134
44977efed303 Significant performance optimizations
wizard
parents: 133
diff changeset
416 return $this->ds->create(\%book);
111
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
417 }
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
418
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
419 =end code
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
420
6c25ea91c985 ControllerUnit concept
wizard
parents: 110
diff changeset
421 =cut