Mercurial > pub > Impl
annotate Lib/IMPL/DOM/Transform/QueryToDOM.pm @ 323:b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
author | sergey |
---|---|
date | Thu, 23 May 2013 18:40:26 +0400 |
parents | c9c2ec29793f |
children | 34a110d1f06c |
rev | line source |
---|---|
237 | 1 package IMPL::DOM::Transform::QueryToDOM; |
2 use strict; | |
3 | |
4 use IMPL::Const qw(:prop); | |
5 use IMPL::declare { | |
6 base => [ | |
7 'IMPL::DOM::Transform::ObjectToDOM' => '@_' | |
8 ], | |
9 props => [ | |
10 prefix => PROP_RO, | |
238 | 11 delimiter => PROP_RO |
237 | 12 ] |
13 }; | |
14 | |
15 sub CTOR { | |
16 my ($this) = @_; | |
17 | |
264 | 18 $this->templates->{'CGI'} = 'TransformCGI'; |
323
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
19 $this->templates->{'IMPL::Web::Application::Action'} = 'TransformAction'; |
244 | 20 |
238 | 21 $this->delimiter('[.]'); |
22 $this->prefix(''); | |
237 | 23 } |
24 | |
250 | 25 # inflate simple properties |
26 sub TransformPlain { | |
27 my ($this,$data) = @_; | |
28 | |
29 $this->currentNode->nodeProperty( rawValue => $data ); | |
30 $this->currentNode->nodeValue( $this->inflateNodeValue($data) ); | |
31 return $this->currentNode; | |
32 } | |
33 | |
34 # do not store complex data as node values | |
35 sub StoreObject { | |
36 my ($this,$node,$data) = @_; | |
37 | |
38 return $node; | |
39 } | |
40 | |
264 | 41 #TODO: support a.b[0][1].c[1] |
42 | |
237 | 43 sub TransformCGI { |
44 my ($this,$query) = @_; | |
323
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
45 |
237 | 46 my $data={}; |
47 | |
48 my $prefix = $this->prefix; | |
49 my $delim = $this->delimiter; | |
50 | |
51 foreach my $param (grep index($_,$prefix) >= 0 , $query->param()) { | |
244 | 52 |
53 my @value = grep length($_), $query->param($param) or next; | |
237 | 54 |
238 | 55 my @parts = split /$delim/,$param; |
237 | 56 |
57 my $node = $data; | |
58 while ( my $part = shift @parts ) { | |
238 | 59 if (my ($name,$index) = ($part =~ m/^(\w+)(?:\[(\d+)\])?$/) ) { |
60 if (@parts) { | |
61 if(defined $index) { | |
62 $node = ($node->{$name}[$index] ||= {}); | |
63 } else { | |
64 $node = ($node->{$name} ||= {}); | |
65 } | |
66 } else { | |
67 if(defined $index) { | |
244 | 68 $node->{$name}[$index] = (@value == 1 ? $value[0] : \@value); |
238 | 69 } else { |
244 | 70 $node->{$name} = (@value == 1 ? $value[0] : \@value); |
238 | 71 } |
72 } | |
237 | 73 } |
74 } | |
75 } | |
76 | |
77 return $this->Transform($data); | |
238 | 78 } |
79 | |
323
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
80 sub TransformAction { |
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
81 my ($this,$action) = @_; |
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
82 |
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
83 return $this->Transform($action->isJson ? $action->jsonData : $action->query); |
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
84 } |
b56b1ec33b59
minor changes to support JSON in transformation from a query to an object
sergey
parents:
264
diff
changeset
|
85 |
264 | 86 1; |
87 | |
88 __END__ | |
89 | |
90 =pod | |
91 | |
92 =head1 NAME | |
93 | |
94 C<IMPL::DOM::Transform::QueryToDOM> - преобразование CGI запроса в DOM документ. | |
95 | |
96 =head1 SYNOPSIS | |
97 | |
98 =begin code | |
99 | |
100 use CGI(); | |
101 use IMPL::require { | |
102 Schema => 'IMPL::DOM::Schema', | |
103 Config => 'IMPL::Config', | |
104 QueryToDOM => 'IMPL::DOM::Transform::QueryToDOM' | |
105 } | |
106 | |
107 my $q = CGI->new(); | |
108 | |
109 my $schema = Schema->LoadSchema(Config->AppBase('schemas','person.xml')); | |
110 my $transorm = QueryToDOM->new('edit', $schema); | |
111 | |
112 my $form = $transform->Transform($q); | |
113 | |
114 my @errors; | |
115 | |
116 push @errors, $transform->buildErrors; | |
117 push @errors, $schema->Validate($doc); | |
118 | |
119 | |
120 =end code | |
121 | |
122 =head1 DESCRIPTION | |
123 | |
124 Наследует C<IMPL::DOM::Transform::ObjectToDOM>. Добавляет метод | |
125 C<TransformCGI> который применятеся к объектам типа C<CGI> (и производных). | |
126 | |
127 Запрос C<CGI> сначала приводится к хешу, затем полученный хеш преобразуется | |
128 в DOM документ при помощи вызова метода C<Transform>. | |
129 | |
130 Для этого выбираются параметры запроса, затем, имя каждого параметра | |
131 рассматривается в виде пути к свойству, создается структура из хешей и массивов | |
132 в которую по указанному пути кладется значение. | |
133 | |
134 Если параметр имеет несколько значений, значит свойство является массивом. | |
135 | |
136 Также изменено поведение некоторых методов преобразования. | |
137 | |
138 =over | |
139 | |
140 =item * C<TransformPlain($value)> | |
141 | |
142 Преобразование для простого значения свойства. Посокльку в запросе передаются | |
143 строковые значения, а схема документа может предполпгать другие типы, при | |
144 преобразовании значения параметра из запроса к значению узла используется | |
145 метод C<< $this->inflateNodeValue($value) >>, также помимо значения | |
146 C<< $this->currentNode->nodeValue >> задается атрибут | |
147 C<< $this->currentNode->nodeProperty( rawValue => $value) >>, для того, чтобы | |
148 была возможность получить оригинальное значение параметра запроса (например, | |
149 в случае когда его формат был не верным и C<nodeValue> будет C<undef>). | |
150 | |
151 =item * C<StoreObject($node,$object)> | |
152 | |
153 Данный метод вызывается если текущий узел (переданный в параметре C<$node>) | |
154 предполагает простое значение, однако в запросе для него было передано сложное | |
155 содержимое. Данная реализация просто игнорирует переданный объект C<$object> | |
156 и возвращает C<$node> без изменений. | |
157 | |
158 =back | |
159 | |
160 =head1 MEMBERS | |
161 | |
162 =head2 C<[get]delimiter> | |
163 | |
164 REGEX. Разделитель свойств в имени параметра, по-умолчанию C<'[.]'> | |
165 | |
166 =head2 C<[get]prefix> | |
167 | |
168 Строка, префикс имен параметров, которые участвуют в формировании документа. | |
169 По-умолчанию пусто. | |
170 | |
171 =cut |