comparison Lib/IMPL/DOM/Navigator/Builder.pm @ 384:4edd36025051

DOM schema refactoring
author cin
date Mon, 10 Feb 2014 17:41:34 +0400
parents 010ceafd0c5a
children
comparison
equal deleted inserted replaced
383:2f16f13b000c 384:4edd36025051
11 use IMPL::DOM::Document; 11 use IMPL::DOM::Document;
12 12
13 BEGIN { 13 BEGIN {
14 private _direct property _schemaNavi => PROP_RW; 14 private _direct property _schemaNavi => PROP_RW;
15 private _direct property _docClass => PROP_RW; 15 private _direct property _docClass => PROP_RW;
16 public _direct property BuildErrors => PROP_RO | PROP_LIST;
17 public _direct property Document => PROP_RO; 16 public _direct property Document => PROP_RO;
18 public _direct property ignoreUndefined => PROP_RO; 17 public _direct property ignoreUndefined => PROP_RO;
19 } 18 }
20 19
21 our %CTOR = ( 20 our %CTOR = (
32 } 31 }
33 32
34 sub NavigateCreate { 33 sub NavigateCreate {
35 my ($this,$nodeName,%props) = @_; 34 my ($this,$nodeName,%props) = @_;
36 35
37 if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { 36 if (my $schemaType = $this->{$_schemaNavi}->NavigateName($nodeName)) {
38 my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node'; 37 my $class = $schemaType->can('nativeType') ? $schemaType->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node';
39 38
40 my $schemaSource = $this->{$_schemaNavi}->SourceSchemaNode; 39 my $schemaNode = $this->{$_schemaNavi}->SourceSchemaNode;
41 40
42 my @errors = $this->inflateProperties($schemaNode,\%props); 41 $props{schemaType} = $schemaType;
43 42 $props{schemaNode} = $schemaNode;
44 $props{schema} = $schemaNode;
45 $props{schemaSource} = $schemaSource;
46 43
47 my $node; 44 my $node;
48 if (! $this->{$Document}) { 45 if (! $this->{$Document}) {
49 # keep reference to the schema document 46 # keep reference to the schema document
50 $props{schemaDocument} = $this->{$_schemaNavi}->schema; 47 $props{schemaDocument} = $this->{$_schemaNavi}->schema;
55 $node = $this->{$Document}->Create($nodeName,$class,\%props); 52 $node = $this->{$Document}->Create($nodeName,$class,\%props);
56 $this->Current->appendChild($node); 53 $this->Current->appendChild($node);
57 $this->internalNavigateNodeSet($node); 54 $this->internalNavigateNodeSet($node);
58 } 55 }
59 56
60 if (@errors) {
61 $this->BuildErrors->Append(
62 map {
63 IMPL::DOM::Schema::ValidationError->new(
64 node => $node,
65 source => $schemaSource,
66 schema => $schemaNode,
67 message => $schemaNode->messageInflateError,
68 error => $_
69 )
70 } @errors
71 );
72 }
73
74 return $node; 57 return $node;
75 } else { 58 } else {
76 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName) 59 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName)
77 if !$this->ignoreUndefined; 60 if !$this->ignoreUndefined;
78 return; 61 return;
79 }
80 }
81
82 sub inflateProperties {
83 my ($this,$schemaNode,$refProps) = @_;
84 my @errors;
85 foreach my $schemaProp ( $schemaNode->selectNodes('Property') ) {
86 next if not exists $refProps->{$schemaProp->name};
87 my $result = eval {$schemaProp->inflateValue($refProps->{$schemaProp->name}) };
88 if (my $e = $@) {
89 push @errors, $e;
90 } else {
91 $refProps->{$schemaProp->name} = $result;
92 }
93 }
94 return @errors;
95 }
96
97 sub inflateValue {
98 my ($this,$value,$node,$strict) = @_;
99
100 $strict ||= 0;
101 $node ||= $this->Current;
102
103 my $nodeSchema = $this->{$_schemaNavi}->Current;
104
105 my $result = eval { $nodeSchema->inflateValue($value) };
106 if (my $e=$@) {
107 $this->BuildErrors->Append(new IMPL::DOM::Schema::ValidationError(
108 schema => $nodeSchema,
109 node => $node,
110 error => $e,
111 message => $nodeSchema->messageInflateError,
112 source => $this->{$_schemaNavi}->SourceSchemaNode
113 ));
114 return $strict ? undef : $value ;
115 } else {
116 return $result;
117 } 62 }
118 } 63 }
119 64
120 sub Back { 65 sub Back {
121 my ($this) = @_; 66 my ($this) = @_;
134 sub restoreState { 79 sub restoreState {
135 my ($this) = @_; 80 my ($this) = @_;
136 81
137 $this->{$_schemaNavi}->restoreState; 82 $this->{$_schemaNavi}->restoreState;
138 $this->SUPER::restoreState; 83 $this->SUPER::restoreState;
139 }
140
141 #compatibility
142 sub buildErrors {
143 goto &BuildErrors;
144 } 84 }
145 85
146 sub document { 86 sub document {
147 goto &Document; 87 goto &Document;
148 } 88 }