Mercurial > pub > Impl
annotate 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 |
rev | line source |
---|---|
49 | 1 package IMPL::DOM::Navigator::Builder; |
2 use strict; | |
3 use warnings; | |
4 | |
5 use base qw(IMPL::Object); | |
6 use IMPL::Class::Property; | |
7 use IMPL::Class::Property::Direct; | |
8 require IMPL::DOM::Navigator::SchemaNavigator; | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
9 require IMPL::DOM::Schema::ValidationError; |
49 | 10 |
11 BEGIN { | |
12 private _direct property _schemaNavi => prop_all; | |
13 private _direct property _nodesPath => prop_all; | |
14 private _direct property _nodeCurrent => prop_all; | |
103 | 15 private _direct property _docClass => prop_all; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
16 public _direct property BuildErrors => prop_get | prop_list; |
49 | 17 public _direct property Document => prop_get | owner_set; |
18 } | |
19 | |
20 sub CTOR { | |
21 my ($this,$docClass,$schema) = @_; | |
22 | |
23 $this->{$_docClass} = $docClass; | |
24 $this->{$_schemaNavi} = $schema ? IMPL::DOM::Navigator::SchemaNavigator->new($schema) : undef; | |
25 } | |
26 | |
27 sub NavigateCreate { | |
28 my ($this,$nodeName,%props) = @_; | |
29 | |
30 if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
31 my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node'; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
32 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
33 my @errors = $this->inflateProperties($schemaNode,\%props); |
49 | 34 |
35 my $node; | |
36 if (! $this->{$Document}) { | |
37 $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); | |
38 } else { | |
39 die new IMPL::InvalidOperationException('Can\t create a second top level element') unless $this->{$_nodeCurrent}; | |
40 $node = $this->{$Document}->Create($nodeName,$class,\%props); | |
41 push @{$this->{$_nodesPath}}, $this->{$_nodeCurrent}; | |
42 $this->{$_nodeCurrent}->appendChild($node); | |
43 } | |
44 | |
45 $this->{$_nodeCurrent} = $node; | |
46 | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
47 if (@errors) { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
48 $this->BuildErrors->Append( |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
49 map { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
50 IMPL::DOM::Schema::ValidationError->new( |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
51 Node => $node, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
52 Source => $this->{$_schemaNavi}->SourceSchemaNode, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
53 Schema => $schemaNode, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
54 Message => $schemaNode->messageInflateError, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
55 Error => $_ |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
56 ) |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
57 } @errors |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
58 ); |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
59 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
60 |
49 | 61 return $node; |
62 } else { | |
63 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); | |
64 } | |
65 } | |
66 | |
103 | 67 sub inflateProperties { |
68 my ($this,$schemaNode,$refProps) = @_; | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
69 my @errors; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
70 foreach my $schemaProp ( $schemaNode->selectNodes('Property') ) { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
71 next if not exists $refProps->{$schemaProp->name}; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
72 my $result = eval {$schemaProp->inflateValue($refProps->{$schemaProp->name}) }; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
73 if (my $e = $@) { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
74 push @errors, $e; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
75 } else { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
76 $refProps->{$schemaProp->name} = $result; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
77 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
78 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
79 return @errors; |
103 | 80 } |
81 | |
82 sub inflateValue { | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
83 my ($this,$value,$node) = @_; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
84 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
85 my $nodeSchema = $this->{$_schemaNavi}->Current; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
86 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
87 my $result = eval { $nodeSchema->inflateValue($value) }; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
88 if (my $e=$@) { |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
89 $this->BuildErrors->Append(new IMPL::DOM::Schema::ValidationError( |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
90 Schema => $nodeSchema, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
91 Node => $node, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
92 Error => $e, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
93 Message => $nodeSchema->messageInflateError, |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
94 Source => $this->{$_schemaNavi}->SourceSchemaNode |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
95 )); |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
96 return $value; |
103 | 97 } else { |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
103
diff
changeset
|
98 return $result; |
103 | 99 } |
100 } | |
101 | |
49 | 102 sub Back { |
103 my ($this) = @_; | |
104 | |
105 $this->{$_schemaNavi}->SchemaBack(); | |
106 $this->{$_nodeCurrent} = pop @{$this->{$_nodesPath}}; | |
107 } | |
108 | |
109 1; | |
110 | |
111 __END__ | |
64 | 112 |
49 | 113 =pod |
114 | |
64 | 115 =head1 NAME |
116 | |
117 C< IMPL::DOM::Navigator::Builder > - Навигатор, строящий документ по указанной схеме. | |
118 | |
49 | 119 =head1 SYNOPSIS |
120 | |
64 | 121 =begin code |
122 | |
49 | 123 my $builder = new IMPL::DOM::Navigator::Builder(new MyApp::Document,$schema); |
124 my $reader = new IMPL::DOM::XMLReader(Navigator => $builder); | |
125 | |
126 $reader->ParseFile("document.xml"); | |
127 | |
128 my @errors = $schema->Validate($builder->Document); | |
129 | |
64 | 130 =end code |
131 | |
49 | 132 =head1 DESCRIPTION |
133 | |
134 Построитель DOM документов по указанной схеме. Обычно используется в связке | |
135 с объектами для чтения такими как C<IMPL::DOM::XMLReader>. | |
136 | |
137 =head1 METHODS | |
138 | |
139 =over | |
140 | |
64 | 141 =item C< CTOR($classDocument,$schema) > |
49 | 142 |
64 | 143 Создает новый объект, принимает на вход класс документа (или фабрику, например |
144 L<IMPL::Object::Factory>) и схему. В процессе процедуры построения документа | |
145 будет создан объект документа. | |
49 | 146 |
64 | 147 =item C< NavigateCreate($nodeName,\%props) > |
49 | 148 |
149 Создает новый узел с указанным именем и переходит в него. В случае если в схеме | |
150 подходящий узел не найден, то вызывается исключение. | |
151 | |
152 При этом по имени узла ищется его схема, после чего определяется класс для | |
64 | 153 создания экземпляра и созданный узел доавляется в документ. При создании |
154 нового узла используется метод документа C<< IMPL::DOM::Document->Create >> | |
49 | 155 |
64 | 156 Свойства узла передаются при создании через параметр C<props>, но имя создаваемого |
157 узла НЕ может быть переопределено свойством C<nodeName>, оно будет проигнорировано. | |
158 | |
159 =item C< Document > | |
160 | |
161 Свойство, которое содержит документ по окончании процедурв построения. | |
49 | 162 |
163 =back | |
164 | |
165 =cut |