Mercurial > pub > Impl
view Lib/IMPL/DOM/Transform/ObjectToDOM.pm @ 236:2904da230022
DOM refactoring
author | sergey |
---|---|
date | Mon, 15 Oct 2012 04:23:01 +0400 |
parents | |
children | 61db68166c37 |
line wrap: on
line source
package IMPL::DOM::Transform::ObjectToDOM; use strict; use IMPL::Const qw(:prop :access); use IMPL::declare { require => { PropertyInfo => 'IMPL::Class::PropertyInfo', Builder => 'IMPL::DOM::Navigator::Builder', Exception => 'IMPL::Exception', ArgumentException => '-IMPL::InvalidArgumentException', OperationException => '-IMPL::InvalidOperationException' }, base => [ 'IMPL::Transform' => sub { -plain => \&TransformPlain, HASH => \&TransformHash, -default => \&TransformDefault } ], props => [ documentSchema => PROP_RO, _schema => PROP_RW, _navi => PROP_RW ] }; sub CTOR { my ($this,$docName,$docSchema) = @_; my $docNodeSchema = $docSchema->selectSingleNode(sub { $_->name eq $docName }) or die OperationException->new("Can't find a node schema for the document '$docName'"); my $docClass = ($docNodeSchema->can('nativeType') ? $docNodeSchema->nativeType : undef) || 'IMPL::DOM::Document'; $this->documentSchema($docNodeSchema); $this->_navi( Builder->new( $docClass, $docSchema, ignoreUndefined => 1 ) ); $this->_schema($docSchema); $this->_navi->NavigateCreate($docName); } sub TransformPlain { my ($this,$data) = @_; $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) ); return $this->_navi->Current; } sub TransformHash { my ($this,$data) = @_; die ArgumentException->new(data => 'A HASH reference is required') unless ref $data eq 'HASH'; KEYLOOP: foreach my $key (keys %$data) { my $value = $data->{$key}; if (ref $value eq 'ARRAY') { foreach my $subval (@$value) { my $node = $this->_navi->NavigateCreate($key); unless(defined $node) { $this->_navi->Back(); next KEYLOOP; } $this->Transform($subval); $this->_navi->Back(); } } else { my $node = $this->_navi->NavigateCreate($key); unless(defined $node) { $this->_navi->Back(); next KEYLOOP; } $this->Transform($value); $this->_navi->Back(); } } return $this->_navi->Current; } sub TransformDefault { my ($this,$data) = @_; if ( ref $data and eval { $data->can('GetMeta') } ) { my %props = map { $_->name, 1 } $data->GetMeta(PropertyInfo, sub { $_->access == ACCESS_PUBLIC }, 1 ); my %values = map { $_, $data->$_(); } keys %props; return $this->Transform(\%values); } else { die OperationException->new("Don't know how to transform $data"); } return $this->_navi->Current; } sub buildErrors { my ($this) = @_; return $this->_navi->buildErrors; } 1; __END__ =pod =head1 NAME C<IMPL::DOM::Transform::ObjectToDOM> -преобразование объекта =head1 SYNOPSIS =cut