comparison Lib/IMPL/Web/TT/Form.pm @ 194:4d0e1962161c

Replaced tabs with spaces IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
author cin
date Tue, 10 Apr 2012 20:08:29 +0400
parents d1676be8afcc
children
comparison
equal deleted inserted replaced
193:8e8401c0aea4 194:4d0e1962161c
7 use IMPL::DOM::Navigator::SchemaNavigator(); 7 use IMPL::DOM::Navigator::SchemaNavigator();
8 8
9 __PACKAGE__->PassThroughArgs; 9 __PACKAGE__->PassThroughArgs;
10 10
11 BEGIN { 11 BEGIN {
12 public property base => prop_all; 12 public property base => prop_all;
13 public property schema => prop_all; 13 public property schema => prop_all;
14 public property errors => prop_all; 14 public property errors => prop_all;
15 public property data => prop_all; 15 public property data => prop_all;
16 public property state => prop_all; 16 public property state => prop_all;
17 public property formResult => prop_all; 17 public property formResult => prop_all;
18 } 18 }
19 19
20 sub CTOR { 20 sub CTOR {
21 my ($this) = @_; 21 my ($this) = @_;
22 22
23 if (my $form = $this->formResult) { 23 if (my $form = $this->formResult) {
24 $this->base($form->{formName}); 24 $this->base($form->{formName});
25 $this->errors($form->{formErrors}); 25 $this->errors($form->{formErrors});
26 $this->data($form->{formData}); 26 $this->data($form->{formData});
27 $this->schema($form->{formSchema}); 27 $this->schema($form->{formSchema});
28 $this->state($form->{state}); 28 $this->state($form->{state});
29 } else { 29 } else {
30 30
31 $this->base($this->nodeName) unless $this->base; 31 $this->base($this->nodeName) unless $this->base;
32 32
33 die new IMPL::InvalidArgumentException('A schema is required for a form',$this->nodeName) 33 die new IMPL::InvalidArgumentException('A schema is required for a form',$this->nodeName)
34 unless eval { $this->schema->isa( typeof IMPL::DOM::Schema ) }; 34 unless eval { $this->schema->isa( typeof IMPL::DOM::Schema ) };
35 35
36 die new IMPL::InvalidOperationException('Can\'t find a form definition in a schema',$this->nodeName,$this->base) 36 die new IMPL::InvalidOperationException('Can\'t find a form definition in a schema',$this->nodeName,$this->base)
37 unless $this->schema->selectNodes(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); 37 unless $this->schema->selectNodes(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base });
38 } 38 }
39 39
40 $this->errors([]) unless $this->errors; 40 $this->errors([]) unless $this->errors;
41 } 41 }
42 42
43 sub fillContents { 43 sub fillContents {
44 my ($this) = @_; 44 my ($this) = @_;
45 45
46 my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); 46 my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base });
47 47
48 $this->buildContainer( 48 $this->buildContainer(
49 $schema, 49 $schema,
50 $schema, 50 $schema,
51 $this->data->isComplex ? $this->data : undef, 51 $this->data->isComplex ? $this->data : undef,
52 $this 52 $this
53 ); 53 );
54 } 54 }
55 55
56 sub buildContainer { 56 sub buildContainer {
57 my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_; 57 my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_;
58 58
59 $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}]; 59 $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}];
60 60
61 $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection'); 61 $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection');
62 62
63 foreach my $schemaItem ( $schema->content->childNodes ) { 63 foreach my $schemaItem ( $schema->content->childNodes ) {
64 my $schemaItemSource = $schemaItem; 64 my $schemaItemSource = $schemaItem;
65 65
66 $schemaItem = $this->schema->resolveType($schemaItem->type) 66 $schemaItem = $this->schema->resolveType($schemaItem->type)
67 if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node; 67 if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node;
68 68
69 my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode; 69 my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode;
70 70
71 push @nodesData, undef unless @nodesData; 71 push @nodesData, undef unless @nodesData;
72 72
73 if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) { 73 if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) {
74 $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData; 74 $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData;
75 } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) { 75 } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) {
76 $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData; 76 $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData;
77 } 77 }
78 } 78 }
79 79
80 return $container; 80 return $container;
81 } 81 }
82 82
83 sub buildControl { 83 sub buildControl {
84 my ($this,$schemaSource,$schema,$node,$path) = @_; 84 my ($this,$schemaSource,$schema,$node,$path) = @_;
85 85
86 my @errors; 86 my @errors;
87 87
88 if ($node) { 88 if ($node) {
89 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; 89 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors};
90 } else { 90 } else {
91 @errors = grep $_->Schema == $schemaSource, @{$this->errors}; 91 @errors = grep $_->Schema == $schemaSource, @{$this->errors};
92 } 92 }
93 93
94 return $this->document->CreateControl( 94 return $this->document->CreateControl(
95 $schemaSource->name, 95 $schemaSource->name,
96 $this->mapType($schemaSource), 96 $this->mapType($schemaSource),
97 { 97 {
98 schema => $schema, 98 schema => $schema,
99 sourceSchema => $schemaSource, 99 sourceSchema => $schemaSource,
100 errors => \@errors, 100 errors => \@errors,
101 data => $node, 101 data => $node,
102 inputType => $schemaSource->nodeProperty('inputType') || $schema->nodeProperty('inputType'), 102 inputType => $schemaSource->nodeProperty('inputType') || $schema->nodeProperty('inputType'),
103 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through 103 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through
104 queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}]) 104 queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}])
105 } 105 }
106 ); 106 );
107 } 107 }
108 108
109 sub mapType { 109 sub mapType {
110 my ($this,$schema) = @_; 110 my ($this,$schema) = @_;
111 111
112 $schema->nodeProperty('control') || 112 $schema->nodeProperty('control') ||
113 ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') ) 113 ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') )
114 or die new IMPL::Exception("Unable to get control class for the form element",$schema->path); 114 or die new IMPL::Exception("Unable to get control class for the form element",$schema->path);
115 } 115 }
116 116
117 sub makeParameterName { 117 sub makeParameterName {
118 my ($this,$path) = @_; 118 my ($this,$path) = @_;
119 119
120 join '/', map { 120 join '/', map {
121 $_->{node} ? 121 $_->{node} ?
122 ( 122 (
123 $_->{node}->nodeProperty('instanceId') ? 123 $_->{node}->nodeProperty('instanceId') ?
124 $_->{node}->nodeName . '['. ']' : 124 $_->{node}->nodeName . '['. ']' :
125 $_->{node}->nodeName 125 $_->{node}->nodeName
126 ) : 126 ) :
127 ( 127 (
128 $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ? 128 $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ?
129 $_->{schemaSource}->name . '[0]' : 129 $_->{schemaSource}->name . '[0]' :
130 $_->{schemaSource}->name 130 $_->{schemaSource}->name
131 ) 131 )
132 } @$path; 132 } @$path;
133 } 133 }
134 134
135 sub makeControlArgs{ 135 sub makeControlArgs{
136 my ($this,$path) = @_; 136 my ($this,$path) = @_;
137 137
138 my $navi = new IMPL::DOM::Navigator::SchemaNavigator($this->schema); 138 my $navi = new IMPL::DOM::Navigator::SchemaNavigator($this->schema);
139 my @path = ($this->base, split(/\./,$path) ); 139 my @path = ($this->base, split(/\./,$path) );
140 140
141 $navi->NavigateName($_) or die new IMPL::InvalidArgumentException( 141 $navi->NavigateName($_) or die new IMPL::InvalidArgumentException(
142 "Can't find a definition for an element", 142 "Can't find a definition for an element",
143 $_, 143 $_,
144 $path, 144 $path,
145 $this->element, 145 $this->element,
146 ) foreach @path; 146 ) foreach @path;
147 147
148 my $schema = $navi->Current; 148 my $schema = $navi->Current;
149 my $sourceSchema = $navi->SourceSchemaNode; 149 my $sourceSchema = $navi->SourceSchemaNode;
150 my $queryParameter = join '/', @path; 150 my $queryParameter = join '/', @path;
151 shift @path; 151 shift @path;
152 my $node = $this->data ? $this->data->selectSingleNode(@path) : undef; 152 my $node = $this->data ? $this->data->selectSingleNode(@path) : undef;
153 153
154 my @errors; 154 my @errors;
155 155
156 if ($node) { 156 if ($node) {
157 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; 157 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors};
158 } else { 158 } else {
159 @errors = grep $_->Schema == $sourceSchema, @{$this->errors}; 159 @errors = grep $_->Schema == $sourceSchema, @{$this->errors};
160 } 160 }
161 161
162 return { 162 return {
163 schema => $schema, 163 schema => $schema,
164 sourceSchema => $sourceSchema, 164 sourceSchema => $sourceSchema,
165 errors => \@errors, 165 errors => \@errors,
166 data => $node, 166 data => $node,
167 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through 167 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through
168 queryParameter => $queryParameter, 168 queryParameter => $queryParameter,
169 inputType => $sourceSchema->nodeProperty('inputType') || $schema->nodeProperty('inputType') 169 inputType => $sourceSchema->nodeProperty('inputType') || $schema->nodeProperty('inputType')
170 }; 170 };
171 } 171 }
172 172
173 sub makeContent { 173 sub makeContent {
174 my ($this,$mappings) = @_; 174 my ($this,$mappings) = @_;
175 175
176 my $formSchema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base } ) 176 my $formSchema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base } )
177 or die new Exception("Cant find a schema element for the specified form", $this->base); 177 or die new Exception("Cant find a schema element for the specified form", $this->base);
178 178
179 my $doc = $this->document; 179 my $doc = $this->document;
180 foreach my $itemSchema ( $formSchema->content->childNodes ) { 180 foreach my $itemSchema ( $formSchema->content->childNodes ) {
181 my $itemName = $itemSchema->name; 181 my $itemName = $itemSchema->name;
182 if (my $controlClass = $mappings->{$itemName} ) { 182 if (my $controlClass = $mappings->{$itemName} ) {
183 my $contorl = $doc->CreateControl($itemName,$controlClass,$this->makeControlArgs($itemName)); 183 my $contorl = $doc->CreateControl($itemName,$controlClass,$this->makeControlArgs($itemName));
184 $this->appendChild($contorl); 184 $this->appendChild($contorl);
185 } 185 }
186 } 186 }
187 return; 187 return;
188 } 188 }
189 189
190 sub formErrors { 190 sub formErrors {
191 my ($this) = @_; 191 my ($this) = @_;
192 192
193 if (my $node = $this->data ) { 193 if (my $node = $this->data ) {
194 return [ 194 return [
195 grep { 195 grep {
196 ( $_->Node || $_->Parent) == $node 196 ( $_->Node || $_->Parent) == $node
197 } @{$this->errors} 197 } @{$this->errors}
198 ]; 198 ];
199 } else { 199 } else {
200 return []; 200 return [];
201 } 201 }
202 } 202 }
203 203
204 1; 204 1;
205 __END__ 205 __END__
206 206