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) = @_;