Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Navigator/Builder.pm @ 34:a8086f85a571
Dom Builder
author | Sergey |
---|---|
date | Mon, 16 Nov 2009 18:39:25 +0300 |
parents | 7f00786f8210 |
children | f25d021780b3 |
comparison
equal
deleted
inserted
replaced
33:0004faa276dc | 34:a8086f85a571 |
---|---|
1 package IMPL::DOM::Navigator::Builder; | 1 package IMPL::DOM::Navigator::Builder; |
2 use strict; | 2 use strict; |
3 use warnings; | 3 use warnings; |
4 | 4 |
5 use base qw(IMPL::DOM::Navigator); | 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 | 9 |
10 BEGIN { | 10 BEGIN { |
11 protected _direct property _schemaNavi => prop_all; | 11 private _direct property _schemaNavi => prop_all; |
12 private _direct property _nodesPath => prop_all; | |
13 private _direct property _nodeCurrent => prop_all; | |
14 private _direct property _docClass => prop_all | |
12 public _direct property Document => prop_get | owner_set; | 15 public _direct property Document => prop_get | owner_set; |
13 } | 16 } |
14 | 17 |
15 our %CTOR = ( | |
16 'IMPL::DOM::Navigator' => sub { $_[0] } # IMPL::DOM::Navigator($domDocument) | |
17 ); | |
18 | |
19 sub CTOR { | 18 sub CTOR { |
20 my ($this,$domDocument,$schema) = @_; | 19 my ($this,$docClass,$schema) = @_; |
21 | 20 |
22 $this->{$Document} = $domDocument; | 21 $this->{$_docClass} = $docClass; |
23 $this->{$_schemaNavi} = $schema; | 22 $this->{$_schemaNavi} = IMPL::DOM::Navigator::SchemaNavigator->new($schema); |
24 } | 23 } |
25 | 24 |
26 sub NavigateCreate { | 25 sub NavigateCreate { |
27 my ($this,$nodeName,%props) = @_; | 26 my ($this,$nodeName,%props) = @_; |
28 | 27 |
29 | 28 if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { |
29 my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType : 'IMPL::DOM::Node'; | |
30 | |
31 my $node; | |
32 if (! $this->{$Document}) { | |
33 $node = $this->{$Document} = $this->{$_docClass}->new(nodeName => $nodeName,%props); | |
34 } else { | |
35 die new IMPL::InvalidOperationException('Can\t create a second top level element'); | |
36 $node = $this->{$Document}->Create($nodeName,$class,\%props); | |
37 push @{$this->{$_nodesPath}}, $this->{$_nodeCurrent}; | |
38 $this->{$_nodeCurrent}->appendChild($node); | |
39 } | |
40 | |
41 $this->{$_nodeCurrent} = $node; | |
42 | |
43 return $node; | |
44 } else { | |
45 die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); | |
46 } | |
30 } | 47 } |
31 | 48 |
32 sub Back { | 49 sub Back { |
33 my ($this) = @_; | 50 my ($this) = @_; |
34 | 51 |
52 $this->{$_schemaNavi}->SchemaBack(); | |
53 $this->{$_nodeCurrent} = pop @{$this->{$_nodesPath}}; | |
35 } | 54 } |
36 | 55 |
37 1; | 56 1; |
38 | 57 |
39 __END__ | 58 __END__ |
65 =item C<< $obj->NavigateCreate($nodeName) >> | 84 =item C<< $obj->NavigateCreate($nodeName) >> |
66 | 85 |
67 Создает новый узел с указанным именем и переходит в него. В случае если в схеме | 86 Создает новый узел с указанным именем и переходит в него. В случае если в схеме |
68 подходящий узел не найден, то вызывается исключение. | 87 подходящий узел не найден, то вызывается исключение. |
69 | 88 |
70 При этом схема узла производится по имени, после чего определяется класс для | 89 При этом по имени узла ищется его схема, после чего определяется класс для |
71 создания узла, по алгоритму | 90 создания экземпляра и созданный узел доавляется в документ. |
72 | 91 |
73 =over | 92 Также имя создаваемого узла НЕ может быть переопределено свойством nodeName, оно |
74 | 93 будет проигнорировано. |
75 =item Проверяется свойство C<type> и если оно есть, то используется оно | |
76 | |
77 =item Проверяется свойство C<type> самого элемента схемы, если оно есть, то | |
78 используется оно. | |
79 | |
80 =item В качестве класса берется имя узла | |
81 | |
82 =back | |
83 | |
84 Также имя создаваемого узла может быть переопределено свойством C<nodeName>. | |
85 | |
86 Т.о. узел вида C<< <ComplexNode nodeName="Box" type="Container"> >> приведет | |
87 к созданию C<< Container->new(nodeName => 'Box') >>. | |
88 | 94 |
89 =back | 95 =back |
90 | 96 |
91 =cut | 97 =cut |