Mercurial > pub > Impl
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 |