Mercurial > pub > Impl
view lib/IMPL/DOM/Transform/PostToDOM.pm @ 418:3f38dabaf5cc ref20150831
sync
author | cin |
---|---|
date | Mon, 28 Dec 2015 15:11:35 +0300 |
parents | c6e90e02dd17 |
children |
line wrap: on
line source
package IMPL::DOM::Transform::PostToDOM; use strict; use warnings; use IMPL::Const qw(:prop); use IMPL::declare { require => { Builder => 'IMPL::DOM::Navigator::Builder' }, base => [ 'IMPL::Transform' => sub { -plain => \&TransformPlain, HASH => \&TransformContainer, CGI => \&TransformCGI, CGIWrapper => \&TransformCGI } ], props => [ documentClass => PROP_RO, documentSchema => PROP_RO, prefix => PROP_RO, _navi => PROP_RW, errors => PROP_RW | PROP_LIST, _schema => PROP_RW ] }; sub CTOR { my ($this,$docClass,$docSchema,$prefix) = @_; $docClass ||= 'IMPL::DOM::Document'; $this->_navi( IMPL::DOM::Navigator::Builder->new( $docClass, $docSchema ) ); $this->_schema($docSchema); $this->prefix($prefix) if $prefix; } sub TransformContainer { my ($this,$data) = @_; my $navi = $this->_navi; foreach my $key ( sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2]} map [$_,/(\w+)(?:\[(\d+)\])?/], keys %$data ){ my $value = $data->{$key->[0]}; my $node = $navi->NavigateCreate($key->[1]); $node->nodeProperty(instanceId => $key->[2]) if defined $key->[2]; $this->Transform($value); $navi->Back(); } return $navi->Current; } sub TransformPlain { my ($this,$data) = @_; $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) ); } sub TransformCGI { my ($this,$query) = @_; my $data={}; my $prefix = $this->prefix; my $delim = $this->delimiter; foreach my $param (grep index($_,$prefix) >= 0 , $query->param()) { length (my $value = $query->param($param)) or next; my @parts = split /\//,$param; my $node = $data; while ( my $part = shift @parts ) { if (@parts) { $node = ($node->{$part} ||= {}); } else { $node->{$part} = $value; } } } if (keys %$data > 1) { $data = { document => $data }; } my $doc = $this->Transform($data); $doc->nodeProperty( query => $query ); $this->errors->Append( $this->_navi->BuildErrors); $this->errors->Append( $this->_schema->Validate($doc)); return $doc; } 1; __END__ =pod =head1 NAME C<IMPL::DOM::Transform::PostToDOM> - Преобразование объекта C<CGI> в DOM документ. =head1 SINOPSYS =begin code my $schema = IMPL::DOM::Schema->LoadSchema('Data/user.add.schema.xml'); my $transform = IMPL::DOM::Transform::PostToDOM->new( undef, # default class $schema, $schema->selectSingleNode('ComplexNode')->name ); my $doc = $transform->Transform( CGI->new({ 'user/login' => 'bob', 'user/fullName' => 'Bob Marley', 'user/password' => 'secret', 'user/password_retype' => 'secret', 'user/birthday' => '1978-12-17', 'user/email[1]' => 'bob@marley.com', 'user/email[2]' => 'bob.marley@google.com', process => 1 }) ); =end code =head1 DESCRIPTION Используется для преобразования CGI запроса в DOM документ. Для этого используются параметры запроса, имена которых начинаются со значение из свойства C<prefix>. Имена параметров интерпретируются следующим образом =over =item 1 Имя параметра составляется из имени узла, имен всех его родителей и указанием номера экземпляра. =item 2 Имена узлов могут содержать только буквы, цифры и символ _ =item 3 В случае когда узел может повторяться несколько раз, в квадратных скобках указывается послеовательный номер экземпляра. =item 4 Имена параметров объединяются через символ '/' =back =cut