Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Transform/ObjectToDOM.pm @ 250:129e48bb5afb
DOM refactoring
ObjectToDOM methods are virtual
QueryToDOM uses inflators
Fixed transform for the complex values in the ObjectToDOM
QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author | sergey |
---|---|
date | Wed, 07 Nov 2012 04:17:53 +0400 |
parents | 2746a8e5a6c4 |
children | 299af584c05f |
comparison
equal
deleted
inserted
replaced
249:0057f48f7945 | 250:129e48bb5afb |
---|---|
10 ArgumentException => '-IMPL::InvalidArgumentException', | 10 ArgumentException => '-IMPL::InvalidArgumentException', |
11 OperationException => '-IMPL::InvalidOperationException' | 11 OperationException => '-IMPL::InvalidOperationException' |
12 }, | 12 }, |
13 base => [ | 13 base => [ |
14 'IMPL::Transform' => sub { | 14 'IMPL::Transform' => sub { |
15 -plain => \&TransformPlain, | 15 -plain => 'TransformPlain', |
16 HASH => \&TransformHash, | 16 HASH => 'TransformHash', |
17 -default => \&TransformDefault | 17 -default => 'TransformDefault' |
18 } | 18 } |
19 ], | 19 ], |
20 props => [ | 20 props => [ |
21 documentSchema => PROP_RO, | 21 documentSchema => PROP_RO, |
22 _schema => PROP_RW, | 22 _schema => PROP_RW, |
23 _navi => PROP_RW | 23 _navi => PROP_RW |
24 ] | 24 ] |
25 }; | 25 }; |
26 | 26 |
27 use constant { | 27 use constant { |
28 SchemaNode => 'IMPL::DOM::Schema::Node' | 28 SchemaNode => 'IMPL::DOM::Schema::Node', |
29 ComplexNode => 'IMPL::DOM::Schema::ComplexNode' | |
29 }; | 30 }; |
30 | 31 |
31 sub CTOR { | 32 sub CTOR { |
32 my ($this,$docName,$docSchema,$transforms) = @_; | 33 my ($this,$docName,$docSchema,$transforms) = @_; |
33 | 34 |
51 } | 52 } |
52 | 53 |
53 sub TransformPlain { | 54 sub TransformPlain { |
54 my ($this,$data) = @_; | 55 my ($this,$data) = @_; |
55 | 56 |
56 $this->_navi->Current->nodeValue( $this->_navi->inflateValue($data) ); | 57 $this->_navi->Current->nodeValue( $data ); |
57 return $this->_navi->Current; | 58 return $this->_navi->Current; |
59 } | |
60 | |
61 sub currentNode { | |
62 shift->_navi->Current; | |
63 } | |
64 | |
65 sub inflateNodeValue { | |
66 shift->_navi->inflateValue(shift); | |
58 } | 67 } |
59 | 68 |
60 sub TransformHash { | 69 sub TransformHash { |
61 my ($this,$data) = @_; | 70 my ($this,$data) = @_; |
62 | 71 |
63 die ArgumentException->new(data => 'A HASH reference is required') | 72 die ArgumentException->new(data => 'A HASH reference is required') |
64 unless ref $data eq 'HASH'; | 73 unless ref $data eq 'HASH'; |
74 | |
75 return $this->StoreObject($this->currentNode,$data) | |
76 if !$this->currentNode->schema->isa(ComplexNode); | |
65 | 77 |
66 KEYLOOP: foreach my $key (keys %$data) { | 78 KEYLOOP: foreach my $key (keys %$data) { |
67 my $value = $data->{$key}; | 79 my $value = $data->{$key}; |
68 | 80 |
69 if (ref $value eq 'ARRAY') { | 81 if (ref $value eq 'ARRAY') { |
70 foreach my $subval (@$value) { | 82 foreach my $subval (@$value) { |
71 | 83 |
84 $this->_navi->saveState(); | |
85 | |
72 my $node = $this->_navi->NavigateCreate($key); | 86 my $node = $this->_navi->NavigateCreate($key); |
73 | 87 |
74 unless(defined $node) { | 88 unless(defined $node) { |
75 $this->_navi->Back(); | 89 #$this->_navi->Back(); |
90 $this->_navi->restoreState(); | |
76 next KEYLOOP; | 91 next KEYLOOP; |
77 } | 92 } |
93 | |
94 $this->_navi->applyState(); | |
78 | 95 |
79 $this->Transform($subval); | 96 $this->Transform($subval); |
80 | 97 |
81 $this->_navi->Back(); | 98 $this->_navi->Back(); |
82 } | 99 } |
83 } else { | 100 } else { |
101 $this->_navi->saveState(); | |
84 my $node = $this->_navi->NavigateCreate($key); | 102 my $node = $this->_navi->NavigateCreate($key); |
85 | 103 |
86 unless(defined $node) { | 104 unless(defined $node) { |
87 $this->_navi->Back(); | 105 #$this->_navi->Back(); |
106 $this->_navi->restoreState(); | |
88 next KEYLOOP; | 107 next KEYLOOP; |
89 } | 108 } |
109 | |
110 $this->_navi->applyState(); | |
111 | |
112 warn "$key = $value"; | |
90 | 113 |
91 $this->Transform($value); | 114 $this->Transform($value); |
92 | 115 |
93 $this->_navi->Back(); | 116 $this->_navi->Back(); |
94 } | 117 } |
95 } | 118 } |
96 return $this->_navi->Current; | 119 return $this->_navi->Current; |
97 } | 120 } |
98 | 121 |
122 # this method handles situatuions when a complex object must be stored in a | |
123 # simple node. | |
124 sub StoreObject { | |
125 my ($this,$node,$data) = @_; | |
126 | |
127 $node->nodeValue($data); | |
128 | |
129 warn "Stored value for", $node->nodeName; | |
130 | |
131 return $node; | |
132 } | |
133 | |
99 sub TransformDefault { | 134 sub TransformDefault { |
100 my ($this,$data) = @_; | 135 my ($this,$data) = @_; |
136 | |
137 return $this->StoreObject($this->currentNode,$data) | |
138 if !$this->currentNode->schema->isa(ComplexNode); | |
101 | 139 |
102 if ( ref $data and eval { $data->can('GetMeta') } ) { | 140 if ( ref $data and eval { $data->can('GetMeta') } ) { |
103 my %props = map { | 141 my %props = map { |
104 $_->name, 1 | 142 $_->name, 1 |
105 } $data->GetMeta(PropertyInfo, sub { $_->access == ACCESS_PUBLIC }, 1 ); | 143 } $data->GetMeta(PropertyInfo, sub { $_->access == ACCESS_PUBLIC }, 1 ); |