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