Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Navigator/Builder.pm @ 104:196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
Minor and major fixes almost for everything.
A 'Source' property of the ValidationErrors generated from a NodeSet or a NodeList is subject to change in the future.
author | wizard |
---|---|
date | Tue, 11 May 2010 02:42:59 +0400 |
parents | c289ed9662ca |
children | 83e356614c1e |
comparison
equal
deleted
inserted
replaced
103:c289ed9662ca | 104:196bf443b5e1 |
---|---|
4 | 4 |
5 use base qw(IMPL::Object); | 5 use base qw(IMPL::Object); |
6 use IMPL::Class::Property; | 6 use IMPL::Class::Property; |
7 use IMPL::Class::Property::Direct; | 7 use IMPL::Class::Property::Direct; |
8 require IMPL::DOM::Navigator::SchemaNavigator; | 8 require IMPL::DOM::Navigator::SchemaNavigator; |
9 require IMPL::DOM::Schema::ValidationError; | |
9 | 10 |
10 BEGIN { | 11 BEGIN { |
11 private _direct property _schemaNavi => prop_all; | 12 private _direct property _schemaNavi => prop_all; |
12 private _direct property _nodesPath => prop_all; | 13 private _direct property _nodesPath => prop_all; |
13 private _direct property _nodeCurrent => prop_all; | 14 private _direct property _nodeCurrent => prop_all; |
14 private _direct property _docClass => prop_all; | 15 private _direct property _docClass => prop_all; |
16 public _direct property BuildErrors => prop_get | prop_list; | |
15 public _direct property Document => prop_get | owner_set; | 17 public _direct property Document => prop_get | owner_set; |
16 } | 18 } |
17 | 19 |
18 sub CTOR { | 20 sub CTOR { |
19 my ($this,$docClass,$schema) = @_; | 21 my ($this,$docClass,$schema) = @_; |
24 | 26 |
25 sub NavigateCreate { | 27 sub NavigateCreate { |
26 my ($this,$nodeName,%props) = @_; | 28 my ($this,$nodeName,%props) = @_; |
27 | 29 |
28 if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { | 30 if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { |
29 my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType : 'IMPL::DOM::Node'; | 31 my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node'; |
30 $this->inflateProperties($schemaNode,\%props); | 32 |
33 my @errors = $this->inflateProperties($schemaNode,\%props); | |
31 | 34 |
32 my $node; | 35 my $node; |
33 if (! $this->{$Document}) { | 36 if (! $this->{$Document}) { |
34 $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); | 37 $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); |
35 } else { | 38 } else { |
39 $this->{$_nodeCurrent}->appendChild($node); | 42 $this->{$_nodeCurrent}->appendChild($node); |
40 } | 43 } |
41 | 44 |
42 $this->{$_nodeCurrent} = $node; | 45 $this->{$_nodeCurrent} = $node; |
43 | 46 |
47 if (@errors) { | |
48 $this->BuildErrors->Append( | |
49 map { | |
50 IMPL::DOM::Schema::ValidationError->new( | |
51 Node => $node, | |
52 Source => $this->{$_schemaNavi}->SourceSchemaNode, | |
53 Schema => $schemaNode, | |
54 Message => $schemaNode->messageInflateError, | |
55 Error => $_ | |
56 ) | |
57 } @errors | |
58 ); | |
59 } | |
60 | |
44 return $node; | 61 return $node; |
45 } else { | 62 } else { |
46 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); | 63 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); |
47 } | 64 } |
48 } | 65 } |
49 | 66 |
50 sub inflateProperties { | 67 sub inflateProperties { |
51 my ($this,$schemaNode,$refProps) = @_; | 68 my ($this,$schemaNode,$refProps) = @_; |
52 | 69 my @errors; |
53 $refProps->{$_->name} = $_->inflator->new($refProps->{$_->name}) | 70 foreach my $schemaProp ( $schemaNode->selectNodes('Property') ) { |
54 foreach $schemaNode->selectNodes( | 71 next if not exists $refProps->{$schemaProp->name}; |
55 sub { | 72 my $result = eval {$schemaProp->inflateValue($refProps->{$schemaProp->name}) }; |
56 $_->nodeName eq 'Property' and exists $refProps->{$_->name} and $_->inflator | 73 if (my $e = $@) { |
57 } | 74 push @errors, $e; |
58 ); | 75 } else { |
76 $refProps->{$schemaProp->name} = $result; | |
77 } | |
78 } | |
79 return @errors; | |
59 } | 80 } |
60 | 81 |
61 sub inflateValue { | 82 sub inflateValue { |
62 my ($this,$value) = @_; | 83 my ($this,$value,$node) = @_; |
63 my $schemaNode = $this->{$_schemaNavi}->Current; | 84 |
64 if ($schemaNode->can('inflator') and my $inflator = $schemaNode->inflator) { | 85 my $nodeSchema = $this->{$_schemaNavi}->Current; |
65 return $inflator->new($value); | 86 |
87 my $result = eval { $nodeSchema->inflateValue($value) }; | |
88 if (my $e=$@) { | |
89 $this->BuildErrors->Append(new IMPL::DOM::Schema::ValidationError( | |
90 Schema => $nodeSchema, | |
91 Node => $node, | |
92 Error => $e, | |
93 Message => $nodeSchema->messageInflateError, | |
94 Source => $this->{$_schemaNavi}->SourceSchemaNode | |
95 )); | |
96 return $value; | |
66 } else { | 97 } else { |
67 return $value; | 98 return $result; |
68 } | 99 } |
69 } | 100 } |
70 | 101 |
71 sub Back { | 102 sub Back { |
72 my ($this) = @_; | 103 my ($this) = @_; |