112
|
1 package IMPL::DOM::Transform::PostToDOM;
|
49
|
2 use strict;
|
|
3 use warnings;
|
|
4
|
235
|
5 use IMPL::Const qw(:prop);
|
|
6 use IMPL::declare {
|
|
7 require => {
|
|
8 Builder => 'IMPL::DOM::Navigator::Builder'
|
|
9 },
|
|
10 base => [
|
|
11 'IMPL::Transform' => sub {
|
|
12 -plain => \&TransformPlain,
|
|
13 HASH => \&TransformContainer,
|
|
14 CGI => \&TransformCGI,
|
|
15 CGIWrapper => \&TransformCGI
|
|
16 }
|
|
17 ],
|
|
18 props => [
|
|
19 documentClass => PROP_RO,
|
|
20 documentSchema => PROP_RO,
|
|
21 prefix => PROP_RO,
|
|
22 _navi => PROP_RW,
|
|
23 errors => PROP_RW | PROP_LIST,
|
|
24 _schema => PROP_RW
|
|
25 ]
|
|
26 };
|
49
|
27
|
106
|
28 sub CTOR {
|
194
|
29 my ($this,$docClass,$docSchema,$prefix) = @_;
|
|
30 $docClass ||= 'IMPL::DOM::Document';
|
|
31
|
|
32 $this->_navi(
|
|
33 IMPL::DOM::Navigator::Builder->new(
|
|
34 $docClass,
|
|
35 $docSchema
|
|
36 )
|
|
37 );
|
|
38 $this->_schema($docSchema);
|
|
39 $this->prefix($prefix) if $prefix;
|
106
|
40 }
|
|
41
|
113
|
42 sub TransformContainer {
|
49
|
43 my ($this,$data) = @_;
|
|
44
|
112
|
45 my $navi = $this->_navi;
|
113
|
46
|
147
|
47 foreach my $key (
|
194
|
48 sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2]}
|
|
49 map [$_,/(\w+)(?:\[(\d+)\])?/], keys %$data
|
147
|
50 ){
|
194
|
51 my $value = $data->{$key->[0]};
|
|
52 my $node = $navi->NavigateCreate($key->[1]);
|
|
53
|
|
54 $node->nodeProperty(instanceId => $key->[2]) if defined $key->[2];
|
|
55
|
|
56 $this->Transform($value);
|
|
57
|
|
58 $navi->Back();
|
49
|
59 }
|
|
60
|
113
|
61 return $navi->Current;
|
|
62 }
|
|
63
|
|
64 sub TransformPlain {
|
194
|
65 my ($this,$data) = @_;
|
|
66
|
|
67 $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) );
|
49
|
68 }
|
|
69
|
113
|
70 sub TransformCGI {
|
194
|
71 my ($this,$query) = @_;
|
126
|
72
|
194
|
73 my $data={};
|
|
74
|
|
75 my $prefix = $this->prefix;
|
235
|
76 my $delim = $this->delimiter;
|
194
|
77
|
|
78 foreach my $param (grep index($_,$prefix) >= 0 , $query->param()) {
|
|
79 length (my $value = $query->param($param)) or next;
|
|
80
|
|
81 my @parts = split /\//,$param;
|
|
82
|
|
83 my $node = $data;
|
|
84 while ( my $part = shift @parts ) {
|
|
85 if (@parts) {
|
|
86 $node = ($node->{$part} ||= {});
|
|
87 } else {
|
|
88 $node->{$part} = $value;
|
|
89 }
|
|
90 }
|
|
91 }
|
|
92
|
|
93 if (keys %$data > 1) {
|
|
94 $data = { document => $data };
|
|
95 }
|
|
96
|
|
97 my $doc = $this->Transform($data);
|
|
98 $doc->nodeProperty( query => $query );
|
235
|
99 $this->errors->Append( $this->_navi->BuildErrors);
|
|
100 $this->errors->Append( $this->_schema->Validate($doc));
|
194
|
101 return $doc;
|
106
|
102 }
|
49
|
103
|
|
104 1;
|
147
|
105
|
|
106 __END__
|
|
107
|
|
108 =pod
|
|
109
|
|
110 =head1 NAME
|
|
111
|
180
|
112 C<IMPL::DOM::Transform::PostToDOM> - Преобразование объекта C<CGI> в DOM документ.
|
147
|
113
|
|
114 =head1 SINOPSYS
|
|
115
|
|
116 =begin code
|
|
117
|
194
|
118 my $schema = IMPL::DOM::Schema->LoadSchema('Data/user.add.schema.xml');
|
|
119
|
|
120 my $transform = IMPL::DOM::Transform::PostToDOM->new(
|
|
121 undef, # default class
|
|
122 $schema,
|
|
123 $schema->selectSingleNode('ComplexNode')->name
|
|
124 );
|
|
125
|
|
126 my $doc = $transform->Transform(
|
|
127 CGI->new({
|
|
128 'user/login' => 'bob',
|
|
129 'user/fullName' => 'Bob Marley',
|
|
130 'user/password' => 'secret',
|
|
131 'user/password_retype' => 'secret',
|
|
132 'user/birthday' => '1978-12-17',
|
|
133 'user/email[1]' => 'bob@marley.com',
|
|
134 'user/email[2]' => 'bob.marley@google.com',
|
|
135 process => 1
|
|
136 })
|
|
137 );
|
147
|
138
|
|
139 =end code
|
|
140
|
|
141 =head1 DESCRIPTION
|
|
142
|
180
|
143 Используется для преобразования CGI запроса в DOM документ. Для этого используются параметры запроса, имена которых
|
|
144 начинаются со значение из свойства C<prefix>.
|
147
|
145
|
180
|
146 Имена параметров интерпретируются следующим образом
|
147
|
147
|
|
148 =over
|
|
149
|
180
|
150 =item 1 Имя параметра составляется из имени узла, имен всех его родителей и указанием номера экземпляра.
|
147
|
151
|
180
|
152 =item 2 Имена узлов могут содержать только буквы, цифры и символ _
|
147
|
153
|
180
|
154 =item 3 В случае когда узел может повторяться несколько раз, в квадратных скобках указывается
|
|
155 послеовательный номер экземпляра.
|
194
|
156
|
180
|
157 =item 4 Имена параметров объединяются через символ '/'
|
147
|
158
|
|
159 =back
|
|
160
|
|
161 =cut
|