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