comparison Lib/IMPL/DOM/Transform/ObjectToDOM.pm @ 236:2904da230022

DOM refactoring
author sergey
date Mon, 15 Oct 2012 04:23:01 +0400
parents
children 61db68166c37
comparison
equal deleted inserted replaced
235:a4d9126edcbb 236:2904da230022
1 package IMPL::DOM::Transform::ObjectToDOM;
2 use strict;
3
4 use IMPL::Const qw(:prop :access);
5 use IMPL::declare {
6 require => {
7 PropertyInfo => 'IMPL::Class::PropertyInfo',
8 Builder => 'IMPL::DOM::Navigator::Builder',
9 Exception => 'IMPL::Exception',
10 ArgumentException => '-IMPL::InvalidArgumentException',
11 OperationException => '-IMPL::InvalidOperationException'
12 },
13 base => [
14 'IMPL::Transform' => sub {
15 -plain => \&TransformPlain,
16 HASH => \&TransformHash,
17 -default => \&TransformDefault
18 }
19 ],
20 props => [
21 documentSchema => PROP_RO,
22 _schema => PROP_RW,
23 _navi => PROP_RW
24 ]
25 };
26
27 sub CTOR {
28 my ($this,$docName,$docSchema) = @_;
29
30 my $docNodeSchema = $docSchema->selectSingleNode(sub { $_->name eq $docName })
31 or die OperationException->new("Can't find a node schema for the document '$docName'");
32
33 my $docClass = ($docNodeSchema->can('nativeType') ? $docNodeSchema->nativeType : undef) || 'IMPL::DOM::Document';
34
35 $this->documentSchema($docNodeSchema);
36
37 $this->_navi(
38 Builder->new(
39 $docClass,
40 $docSchema,
41 ignoreUndefined => 1
42 )
43 );
44 $this->_schema($docSchema);
45
46 $this->_navi->NavigateCreate($docName);
47 }
48
49 sub TransformPlain {
50 my ($this,$data) = @_;
51
52 $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) );
53 return $this->_navi->Current;
54 }
55
56 sub TransformHash {
57 my ($this,$data) = @_;
58
59 die ArgumentException->new(data => 'A HASH reference is required')
60 unless ref $data eq 'HASH';
61
62 KEYLOOP: foreach my $key (keys %$data) {
63 my $value = $data->{$key};
64
65 if (ref $value eq 'ARRAY') {
66 foreach my $subval (@$value) {
67
68 my $node = $this->_navi->NavigateCreate($key);
69
70 unless(defined $node) {
71 $this->_navi->Back();
72 next KEYLOOP;
73 }
74
75 $this->Transform($subval);
76
77 $this->_navi->Back();
78 }
79 } else {
80 my $node = $this->_navi->NavigateCreate($key);
81
82 unless(defined $node) {
83 $this->_navi->Back();
84 next KEYLOOP;
85 }
86
87 $this->Transform($value);
88
89 $this->_navi->Back();
90 }
91 }
92 return $this->_navi->Current;
93 }
94
95 sub TransformDefault {
96 my ($this,$data) = @_;
97
98 if ( ref $data and eval { $data->can('GetMeta') } ) {
99 my %props = map {
100 $_->name, 1
101 } $data->GetMeta(PropertyInfo, sub { $_->access == ACCESS_PUBLIC }, 1 );
102
103 my %values = map {
104 $_,
105 $data->$_();
106 } keys %props;
107
108 return $this->Transform(\%values);
109 } else {
110 die OperationException->new("Don't know how to transform $data");
111 }
112
113 return $this->_navi->Current;
114 }
115
116 sub buildErrors {
117 my ($this) = @_;
118
119 return $this->_navi->buildErrors;
120 }
121
122 1;
123
124 __END__
125
126 =pod
127
128 =head1 NAME
129
130 C<IMPL::DOM::Transform::ObjectToDOM> -преобразование объекта
131
132 =head1 SYNOPSIS
133
134 =cut